├── .github └── workflows │ └── build.yml ├── .gitignore ├── CMakeLists.txt ├── COPYING ├── ChangeLog ├── INSTALL ├── README.md ├── TODO ├── cmake └── cmake_uninstall.cmake.in ├── config.h.in ├── doc ├── CMakeLists.txt ├── README ├── lua_api.md ├── rc.lua.example ├── termit.1 ├── termit.desktop ├── termit.metainfo.xml ├── termit.png └── termit.svg ├── etc ├── CMakeLists.txt └── termit │ ├── colormaps.lua │ ├── rc.lua │ └── utils.lua ├── po ├── CMakeLists.txt ├── ca.po ├── da.po ├── de.po ├── es.po ├── fr.po ├── hu.po ├── ja.po ├── ko.po ├── nl.po ├── pl.po ├── ru.po ├── sv.po ├── termit.pot └── zh_TW.po ├── src ├── CMakeLists.txt ├── Sources.cmake ├── callbacks.c ├── callbacks.h ├── configs.c ├── configs.h ├── keybindings.c ├── keybindings.h ├── lua_api.c ├── lua_api.h ├── lua_conf.c ├── sessions.c ├── sessions.h ├── termit.c ├── termit.h ├── termit_core_api.c ├── termit_core_api.h ├── termit_preferences.c ├── termit_style.c └── termit_style.h └── utils ├── CMakeLists.txt ├── slack-desc ├── termit.SlackBuild.in ├── termit.ebuild └── termit.spec.in /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build termit 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ubuntu_24: 7 | runs-on: ubuntu-latest 8 | container: 9 | image: ubuntu:24.04 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v2 13 | - name: Prepare build environment. 14 | run: | 15 | apt-get update 16 | apt-get -y install apt-utils 17 | apt-get -y full-upgrade 18 | apt-get install -y gcc cmake lua5.4-dev libgtk-3-dev libvte-2.91 gettext 19 | - name: Configure 20 | run: | 21 | cmake -DCMAKE_BUILD_TYPE=Release . 22 | - name: Build 23 | run: | 24 | make 25 | - name: Install 26 | run: | 27 | make install 28 | - name: Test version 29 | run: | 30 | termit --version 31 | 32 | ubuntu_22: 33 | runs-on: ubuntu-latest 34 | container: 35 | image: ubuntu:22.04 36 | steps: 37 | - name: Checkout 38 | uses: actions/checkout@v2 39 | - name: Prepare build environment. 40 | run: | 41 | apt-get update 42 | apt-get -y install apt-utils 43 | apt-get -y full-upgrade 44 | apt-get install -y gcc cmake lua5.4-dev libgtk-3-dev libvte-2.91 gettext 45 | - name: Configure 46 | run: | 47 | cmake -DCMAKE_BUILD_TYPE=Release . 48 | - name: Build 49 | run: | 50 | make 51 | - name: Install 52 | run: | 53 | make install 54 | - name: Test version 55 | run: | 56 | termit --version 57 | 58 | fedora_latest_build: 59 | runs-on: ubuntu-latest 60 | container: 61 | image: fedora:latest 62 | steps: 63 | - name: Checkout 64 | uses: actions/checkout@v2 65 | with: 66 | fetch-depth: 1000 67 | - name: Prepare build environment. 68 | run: | 69 | dnf -y upgrade 70 | dnf -y install cmake gcc gtk+ vte291 vte291-devel lua lua-devel 71 | - name: Configure 72 | run: | 73 | cmake -DCMAKE_BUILD_TYPE=Release . 74 | - name: Build 75 | run: | 76 | make 77 | - name: Install 78 | run: | 79 | make install 80 | - name: Test version 81 | run: | 82 | termit --version 83 | 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gmo 2 | *~ 3 | CMakeCache.txt 4 | CMakeFiles 5 | Makefile 6 | build 7 | cmake_install.cmake 8 | cmake_uninstall.cmake 9 | config.h 10 | cscope.out 11 | install_manifest.txt 12 | src/termit 13 | tags 14 | termit-*.ebuild 15 | termit.SlackBuild 16 | termit.spec 17 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright © 2007-2023 Evgeny Ratnikov 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | cmake_minimum_required(VERSION 3.6.0 FATAL_ERROR) 17 | PROJECT(TERMIT C) 18 | 19 | SET(CMAKE_VERSION "${CMAKE_CACHE_MAJOR_VERSION}.${CMAKE_CACHE_MINOR_VERSION}.${CMAKE_CACHE_RELEASE_VERSION}") 20 | 21 | INCLUDE(UsePkgConfig) 22 | 23 | ADD_DEFINITIONS(-Wall) 24 | 25 | SET(DEFAULT_XDG_DIR "/etc/xdg") 26 | string(REPLACE ":" ";" XDG_DIRS "$ENV{XDG_CONFIG_DIRS}") 27 | FOREACH(xdgDir ${XDG_DIRS}) 28 | SET(XDG_DIR ${xdgDir}) 29 | BREAK() 30 | ENDFOREACH() 31 | 32 | IF(NOT XDG_DIR) 33 | SET(XDG_DIR "/etc/xdg") 34 | ENDIF(NOT XDG_DIR) 35 | 36 | SET(DEBUG FALSE CACHE BOOL "debug info") 37 | SET(ENABLE_NLS TRUE CACHE BOOL "enable translation") 38 | SET(XDG_DIR ${XDG_DIR} CACHE STRING "default xdg dir") 39 | 40 | SET(TERMIT_PACKAGE "termit") 41 | SET(TERMIT_PACKAGE_VERSION "3.1.0") 42 | SET(TERMIT_LOCALE_DIR "${CMAKE_INSTALL_PREFIX}/share/locale") 43 | SET(TERMIT_XDG_DIR "${XDG_DIR}/termit") 44 | SET(TERMIT_PACKAGE_NAME "termit - terminal emulator") 45 | SET(TERMIT_PACKAGE_STRING "${TERMIT_PACKAGE} ${TERMIT_PACKAGE_VERSION}") 46 | SET(TERMIT_PACKAGE_BUGREPORT "ratnikov.ev@gmail.com") 47 | 48 | CONFIGURE_FILE(${TERMIT_SOURCE_DIR}/config.h.in ${TERMIT_SOURCE_DIR}/config.h) 49 | 50 | CONFIGURE_FILE( 51 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" 52 | "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" 53 | IMMEDIATE @ONLY) 54 | ADD_CUSTOM_TARGET(uninstall 55 | "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake") 56 | 57 | ADD_SUBDIRECTORY(doc) 58 | ADD_SUBDIRECTORY(src) 59 | IF(ENABLE_NLS) 60 | ADD_SUBDIRECTORY(po) 61 | ENDIF(ENABLE_NLS) 62 | ADD_SUBDIRECTORY(utils) 63 | ADD_SUBDIRECTORY(etc) 64 | 65 | MESSAGE("\n termit ${TERMIT_PACKAGE_VERSION}\n") 66 | MESSAGE("Prefix dir:.......... ${CMAKE_INSTALL_PREFIX}") 67 | IF(ENABLE_NLS) 68 | MESSAGE("Locales dir:......... ${TERMIT_LOCALE_DIR}") 69 | ENDIF(ENABLE_NLS) 70 | MESSAGE("Xdg dir:............. ${TERMIT_XDG_DIR}") 71 | message("Gtk:................. ${GTK_VERSION}") 72 | message("Vte:................. ${VTE_VERSION}") 73 | message("Lua:................. ${LUA_VERSION}") 74 | MESSAGE("Debug:............... ${DEBUG}") 75 | MESSAGE("") 76 | 77 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | add gruvbox colormaps (by zzgraph) 2 | refactored several deprecated functions 3 | rename lua_api.txt to md because it is markdown 4 | cmake_minimum_required changed to 3.6.0 5 | require Lua 5.4 6 | new option: 7 | tabCloseButton 8 | removed geometry hints 9 | version 3.1 10 | require Lua 5.3 11 | disable menubar on F10 12 | new options: 13 | scrollOnKeystroke, scrollOnOutput 14 | fixed tab style reset after cancel preferences dialog 15 | refactored several deprecated functions 16 | fixed recursive termit_close_tab call 17 | appdata -> metainfo 18 | default icon name for terminal window 19 | irc colormap (by clort81) 20 | get rid of deprecated match_check 21 | version 3.0 22 | added AppData file 23 | license changed to GPLv3.0+ 24 | added 'apply to all tabs' in preferences dialog 25 | new options: 26 | cursorBlinkMode, cursorShape 27 | startMaximized, hideTitlebarWhenMaximized 28 | wordChars replaced with wordCharExceptions 29 | removed options: 30 | imageFile, transparency, visibleBell 31 | Require libvte>0.29 and Gtk-3. 32 | version 2.10.1 33 | Fixed error with conflicting libvte/Gtk versions 34 | Fixed ebuild (by Ilya Mochalov). 35 | Suppress "invalid option" for -e. 36 | Fixed missing link to math library (by Thomas Koch) 37 | Miminum required version for Gtk-2 changed to 2.24. 38 | Miminum required version for libvte changed to 0.28. 39 | Rebuild po-files due to source changes. 40 | version 2.10.0 41 | fixed compilation for OpenBSD 42 | prevent building termit with incompatible Gtk and Vte versions 43 | "exec" commandline option now works nearly like in xterm 44 | new options: 45 | showBorder - show notebook's borders 46 | version 2.9.6 47 | fixed handling geometry setting 48 | added support to choose libraries while configuring termit build 49 | scrollable tabs in tabbar 50 | new options: 51 | tabPos - set tabbar position 52 | version 2.9.5 53 | fixed bug with hideTabbar and hideSingleTab 54 | tabs indexes start with 1 (Lua-indexing) 55 | fixed desktop file 56 | added Swedish translation (by Tomas Fasth) 57 | version 2.9.4 58 | fix hyphen-used-as-minus-sign in manpage (by Thomas Koch) 59 | new options: 60 | hideTabbar (by Anurag Priyam) 61 | new Lua functions: 62 | toggleTabbar 63 | added Polish translation (by Miś Uszatek) 64 | added Danish translation 65 | added support for Lua 5.2 66 | fixed docs 67 | version 2.9.3 68 | fixed installing as non-root 69 | added Spanish translation (by Martintxo) 70 | added German translation (by Dennis Ploeger) 71 | updated Hungarian translation (by Peter Polonkai) 72 | apply foreground color for bold fonts 73 | added several WM-specific commandline options: --name, --class, --role 74 | version 2.9.2 75 | fix build with --as-needed linker flags enabled (patch by Artur Frysiak) 76 | Meta, Super and Hyper in keybindings (patch by Artur Frysiak) 77 | project language set to C 78 | new Lua functions: 79 | feed feedChild 80 | fixed some compilation issues when using Gtk+3 81 | added Japanese translation (by Nobuhiro Iwamatsu) 82 | version 2.9.1 83 | fixed setEncoding in termit.utils module 84 | fixed possible zombie process 85 | version 2.9.0 86 | new Lua functions: 87 | setColormap 88 | added support for system-wide rc.lua 89 | added support for using modules in rc.lua 90 | added several predefined colormaps 91 | version 2.8.1 92 | fixed bug in currentTabIndex 93 | version 2.8.0 94 | search in vte buffer (only for vte >= 0.26) 95 | new Lua functions 96 | forEachRow 97 | forEachVisibleRow 98 | findDlg findNext findPrev 99 | new options 100 | backspaceBinding 101 | deleteBinding 102 | setStatusbar 103 | extra warnings when compiling in DEBUG mode 104 | fixed docs 105 | version 2.7.1 106 | display proper encoding when switching pages 107 | version 2.7.0 108 | refactored reading table from Lua 109 | fixed working with sessions 110 | new options: 111 | imageFile - path to image to be set on the background 112 | colormap - instead of setColormap 113 | matches - instead of setMatches 114 | tabs - opened by default tabs 115 | changed default binding for 'closeTab' from 'Ctrl-w' to 'CtrlShift-w' 116 | cleanup 117 | fixed docs 118 | version 2.6.0 119 | fixed -e option: read configs first only then execute 120 | accelerators for user menus 121 | new Lua functions 122 | setTabTitleDlg 123 | loadSessionDlg 124 | saveSessionDlg 125 | preferencesDlg 126 | quit 127 | cleanup 128 | fixed docs 129 | removed support for deprecated: 130 | use rc.lua instead of init.lua 131 | in openTab use title instead of name 132 | and workingDir instead of working_dir 133 | action in menuitem must be lua-function 134 | version 2.5.0 135 | GPLv2 license agreement in every source file 136 | new Lua functions 137 | selection 138 | currentTab 139 | global array 'tabs' with tab settings 140 | fixed bug: hidden menu appears after reconfigure 141 | deprecated: 142 | use rc.lua instead of init.lua 143 | in openTab use title instead of name 144 | and workingDir instead of working_dir 145 | fixed docs 146 | version 2.4.0 147 | new Lua functions 148 | setColormap 149 | version 2.3.0 150 | read rc.lua instead of init.lua (init.lua is deprecated) 151 | new Lua functions 152 | new options 153 | audibleBell, visibleBell, setMatches, spawn, urgencyOnBell 154 | version 2.2.0 155 | mixed modifiers (e.g. AltCtrl, AltShift, etc.) 156 | new Lua functions 157 | setTabForegroundColor, setTabBackgroundColor, bindMouse, 158 | toggleMenubar, setWindowTitle, currentTabIndex, getTabTitle, 159 | getWindowTitle 160 | new options 161 | per-tab foreground/background colors, fillTabbar, hideMenubar, 162 | changeTitle 163 | version 2.1.1 164 | fixed typo in docs, init foreground color with "gray", proper Lua-includes 165 | when building from source 166 | version 2.1.0 167 | added support for changing foreground color 168 | added man page 169 | cmake_minimum_required changed to 2.6.1, 2.6.0 have problems with 170 | FindLua51.cmake module 171 | fixed reconfigure when running with --init option 172 | version 2.0.0 173 | embedded Lua - configs and sessions replaced with lua-scripts 174 | xterm-like dynamic window title 175 | version 1.3.5 176 | added Korean translation (by SeonKon Choi) 177 | added termit.spec.in for Fedora 8 (by SeonKon Choi) 178 | fixed bug with show/hide scrollbar 179 | version 1.3.4 180 | fixes Hungarian translation (by Peter Polonkai) 181 | version 1.3.3 182 | added termit.SlackBuild and termit.ebuild 183 | added support for kb_policy (for shortcuts) 184 | versoin 1.3.2 185 | fixed loading default options when no config file was found 186 | added session.example to installed docs 187 | version 1.3.1 188 | added show_scrollbar option in popup menu and termit.cfg 189 | shell_cmd variable splitted into shell (eg bash, zsh, python, etc) 190 | and shell_cmd (eg -c 'su - root', etc) 191 | updated documentation 192 | bugfix with uninitialized GError 193 | fixed --usage output 194 | fixed statusbar encoding when loading session 195 | fixed compilation warnings 196 | version 1.3 197 | when both -s and -e options are presented at command line load session and add tab with command 198 | added --execute/-e command-line option 199 | added hide_single_tab options in termit.cfg (hide tab tray when only one tab is opened) 200 | added configurable keybindings (example here: doc/termit.example) 201 | added support for shell_cmd in session file 202 | added transparent background options in termit.cfg (patch by Tetralet) 203 | added doc/session.example 204 | code cleanup 205 | version 1.2 206 | tabs are reordable for Gtk versions > 2.10.0 207 | added geometry option in termit.cfg (setting COLSxROWS) 208 | --help support 209 | added initial Translation Chinese translation (author Ming Lu) 210 | version 1.1.3 211 | default Sans font replaced with Monospace 212 | fixed linking with option "--as-needed" (patch by Andrew Borodin) 213 | version 1.1.2 214 | bugfix with GError when parsing config files 215 | added hungarian translation (author Peter Polonkai) 216 | added french translation (author Mallory Mollo) 217 | version 1.1.1 218 | important for 64bit platforms: fixes a cast of a pointer to "int" 219 | use pkg-config for detecting vte library 220 | version 1.1 221 | build system changed to CMake (http://www.cmake.org/) 222 | --version (-v) support 223 | added session support 224 | added desktop file according to "Desktop Entry Specification" v1.0 225 | config file placement changed according to "XDG Base Directory Specification" v0.6 226 | version 1.0.3 227 | double-click on empty space in tabbar opens new tab 228 | in debug mode prints pid of child shell process 229 | version 1.0.2 230 | only fixing bootstrap.sh 231 | version 1.0.1 232 | removed unneccessary free - potential "double-free" error 233 | version 1.0 234 | initial release 235 | 236 | 237 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | 5 | Termit requires CMake (version 2.4 or later). You can obtain CMake sources here http://cmake.org/. 6 | 7 | 8 | Run CMake generator: 9 | 10 | cmake . 11 | 12 | Then configure termit: 13 | 14 | ccmake . 15 | 16 | Then make: 17 | 18 | make 19 | 20 | And finally install: 21 | 22 | make install 23 | 24 | Package makers can specify DESTDIR: 25 | 26 | make install DESTDIR="destdir" 27 | 28 | To remove termit: 29 | 30 | make uninstall 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Termit 2 | ====== 3 | 4 | Simple terminal emulator based on vte library, extensible via lua. 5 | 6 | Features: 7 | 8 | * multiple tabs 9 | * switching encodings 10 | * sessions 11 | * configurable keybindings 12 | * embedded Lua 13 | 14 | Configuration can be changed via $HOME/.config/termit/rc.lua file. 15 | Example configurations can be found in doc/rc.lua.example. 16 | 17 | Command-line arguments: 18 | 19 | termit --help 20 | Options: 21 | -h, --help - print this help message 22 | -v, --version - print version number 23 | -e, --execute - execute command 24 | -i, --init=init_file - use init_file instead of standard rc.lua 25 | -n, --name=name - set window name hint 26 | -c, --class=class - set window class hint 27 | -r, --role=role - set window role (Gtk hint) 28 | -T, --title=title - set window title 29 | 30 | Keybindings can be configured via rc.lua. 31 | Defaults are: 32 | 33 | Alt-Left - previous tab 34 | Alt-Right - next tab 35 | Ctrl-t - open tab 36 | Ctlr-w - close tab 37 | Ctrl-Insert - copy 38 | Shift-Insert - paste 39 | 40 | Lua API is described in doc/lua_api.md and in man page. 41 | 42 | Download termit from [here](https://github.com/nonstop/termit/releases). 43 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | -- names for sessions 2 | -- encode displayed buffer (hmmm it seems vte doesn't support that) 3 | -- store in TermitTab only flags: SET_NAME, SET_FG_FONT, SET_BG_FONT, etc 4 | values are already stored in VteTerminal, so we can simply read VteTerminal properties on demand 5 | thus we can achieve smaller memory usage 6 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2007-2010, Evgeny Ratnikov 2 | # 3 | # This file is part of termit. 4 | # termit is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License version 2 6 | # as published by the Free Software Foundation. 7 | # termit is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | # You should have received a copy of the GNU General Public License 12 | # along with termit. If not, see . 13 | 14 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 15 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 16 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 17 | 18 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 19 | STRING(REGEX REPLACE "\n" ";" files "${files}") 20 | FOREACH(file ${files}) 21 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 22 | IF(EXISTS "$ENV{DESTDIR}${file}") 23 | EXEC_PROGRAM( 24 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 25 | OUTPUT_VARIABLE rm_out 26 | RETURN_VALUE rm_retval ) 27 | IF(NOT "${rm_retval}" STREQUAL 0) 28 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 29 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 30 | ELSE(EXISTS "$ENV{DESTDIR}${file}") 31 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 32 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") 33 | ENDFOREACH(file) 34 | 35 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | /* Gettext locale dir */ 18 | #define LOCALEDIR "${TERMIT_LOCALE_DIR}" 19 | 20 | /* Name of package */ 21 | #define PACKAGE "${TERMIT_PACKAGE}" 22 | 23 | /* Define to the address where bug reports for this package should be sent. */ 24 | #define PACKAGE_BUGREPORT "${TERMIT_PACKAGE_BUGREPORT}" 25 | 26 | /* Define to the full name of this package. */ 27 | #define PACKAGE_NAME "${TERMIT_PACKAGE_NAME}" 28 | 29 | /* Define to the full name and version of this package. */ 30 | #define PACKAGE_STRING "${TERMIT_PACKAGE_STRING}" 31 | 32 | /* Define to the version of this package. */ 33 | #define PACKAGE_VERSION "${TERMIT_PACKAGE_VERSION}" 34 | 35 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright © 2007-2023 Evgeny Ratnikov 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | SET(TERMIT_DOCS ../COPYING README lua_api.md rc.lua.example) 17 | 18 | INSTALL(FILES ${TERMIT_DOCS} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/${TERMIT_PACKAGE}) 19 | INSTALL(FILES termit.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) 20 | INSTALL(FILES termit.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) 21 | INSTALL(FILES termit.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo) 22 | 23 | -------------------------------------------------------------------------------- /doc/README: -------------------------------------------------------------------------------- 1 | Termit 2 | 3 | Simple terminal emulator based on vte library, extensible via lua. 4 | 5 | Features: 6 | * multiple tabs 7 | * switching encodings 8 | * sessions 9 | * configurable keybindings 10 | * embedded Lua 11 | Configuration can be changed via $HOME/.config/termit/rc.lua file (example is provided). 12 | 13 | Command-line arguments: 14 | * --version (-v) - prints version info 15 | * --init=init_file - use init_file instead of standard rc.lua 16 | * --execute=cmd - execute command (also -e) 17 | 18 | Keybindings can be configured via rc.lua. 19 | Defaults are: 20 | Alt-Left - previous tab 21 | Alt-Right - next tab 22 | Ctrl-t - open tab 23 | Ctlr-w - close tab 24 | Ctrl-Insert - copy 25 | Shift-Insert - paste 26 | 27 | Lua API is described in lua_api.txt 28 | 29 | -------------------------------------------------------------------------------- /doc/lua_api.md: -------------------------------------------------------------------------------- 1 | h4. Functions 2 | 3 | *activateTab(_tab_index_)* - Activates tab by index. 4 | _tab_index_ - index of tab to activate. Index of the first tab is 1. 5 | 6 | 7 | *addMenu(_menu_)* - Adds menu in menubar. 8 | _menu_ - table of TermitMenuItem type. 9 | 10 | 11 | *addPopupMenu(_menu_)* - Adds menu in popup menu, similar to addMenu. 12 | _menu_ - table of TermitMenuItem type. 13 | 14 | 15 | *bindKey(_keys_, _luaFunction_)* - Sets new keybinding. If luaFunction is nil removes keybinding. 16 | _keys_ - string with keybinding. Available modifiers are Alt Ctrl Shift Meta Super Hyper. 17 | _luaFunction_ - callback function 18 | 19 | pre. Example: don't close tab with Ctrl-w, use CtrlShift-w 20 | bindKey('Ctrl-w', nil) 21 | bindKey('CtrlShift-w', closeTab) 22 | 23 | 24 | *bindMouse(_event_, _luaFunction_)* - Sets new mouse-binding. If luaFunction is nil removes mouse-binding. 25 | _event_ - string with one of those values: DoubleClick 26 | _luaFunction_ - callback function 27 | 28 | 29 | *closeTab()* - Closes active tab. 30 | 31 | 32 | *copy()* - Copies selection into tab's buffer. 33 | 34 | 35 | *currentTab()* - Returns current tab of TermitTabInfo. 36 | 37 | 38 | *currentTabIndex()* - Returns current tab index. 39 | 40 | 41 | *feed(data)* - Interprets data as if it were data received from a terminal process. 42 | 43 | 44 | *feedChild(data)* - Sends a data to the terminal as if it were data entered by the user at the keyboard. 45 | 46 | 47 | *findDlg()* - Opens find entry. (Enabled when build with vte version >= 0.26) 48 | 49 | 50 | *findNext()* - Searches the next string matching search regex. 51 | 52 | 53 | *findPrev()* - Searches the previous string matching search regex. 54 | 55 | 56 | *forEachRow(_func_)* - For each terminal row in entire scrollback buffer executes function passing row as argument. 57 | _func_ - function to be called. 58 | 59 | 60 | *forEachVisibleRow(_func_)* - For each visible terminal row executes function passing row as argument. 61 | _func_ - function to be called. 62 | 63 | 64 | *loadSessionDlg()* - Displays "Load session" dialog. 65 | 66 | 67 | *nextTab()* - Activates next tab. 68 | 69 | 70 | *openTab(_tabInfo_)* - Opens new tab. 71 | _tabinfo_ - table of TermitTabInfo with tab settings. 72 | 73 | pre. Example: 74 | tabInfo = {} 75 | tabInfo.title = 'Zsh tab' 76 | tabInfo.command = 'zsh' 77 | tabInfo.encoding = 'UTF-8' 78 | tabInfo.workingDir = '/tmp' 79 | openTab(tabInfo) 80 | 81 | 82 | *paste()* - Pastes tab's buffer. 83 | 84 | 85 | *preferencesDlg()* - Displays "Preferences" dialog. 86 | 87 | 88 | *prevTab()* - Activates previous tab. 89 | 90 | 91 | *quit()* - Quit. 92 | 93 | 94 | *reconfigure()* - Sets all configurable variables to defaults and forces rereading rc.lua. 95 | 96 | 97 | *saveSessionDlg()* - Displays "Save session" dialog. 98 | 99 | 100 | *selection()* - Returns selected text from current tab. 101 | 102 | 103 | *setColormap(_colormap_)* - Changes colormap for active tab. 104 | _colormap_ - array with 8 or 16 or 24 colors. 105 | 106 | 107 | *setEncoding(_encoding_)* - Changes encoding for active tab. 108 | _encoding_ - string with encoding name. 109 | 110 | pre. Example: 111 | setEncoding('UTF-8') 112 | 113 | 114 | *setKbPolicy(_kb_policy_)* - Sets keyuboard policy for shortcuts. 115 | _kb_policy_ - string with one of those values: 116 | 117 | * keycode - use hardware keyboard codes (XkbLayout-independent) 118 | * keysym - use keysym values (XkbLayout-dependent) 119 | 120 | pre. Example: treat keys via current XkbLayout 121 | setKbPolicy('keysym') 122 | 123 | *setOptions(_opts_)* - Changes default options. 124 | _opts_ - table of TermitOptions type with new options: 125 | 126 | 127 | *setTabBackgroundColor(_color_)* - Changes background color for active tab. 128 | _color_ - string with new color. 129 | 130 | 131 | *setTabFont(_font_)* - Changes font for active tab. 132 | _font_ - string with new font. 133 | 134 | 135 | *setTabForegroundColor(_color_)* - Changes foreground (e.g. font) color for active tab. 136 | _color_ - string with new color. 137 | 138 | 139 | *setTabTitle(_tabTitle_)* - Changes title for active tab. 140 | _tabTitle_ - string with new tab title. 141 | 142 | 143 | *setTabTitleDlg()* - Displays "Set tab title" dialog. 144 | 145 | 146 | *setWindowTitle(_title_)* - Changes termit window title. 147 | _title_ - string with new title. 148 | 149 | 150 | *spawn(_command_) - Spawns command (works via shell). 151 | _command_ - string with command and arguments. 152 | 153 | *toggleMenubar()* - Displays or hides menubar. 154 | 155 | *toggleTabbar()* - Displays or hides tabbar. 156 | 157 | h4. Types 158 | 159 | *TermitCursorBlinkMode* - one of those string values: 160 | 161 | * System - Follow GTK+ settings for cursor blinking 162 | * BlinkOn - Cursor blinks 163 | * BlinkOff - Cursor does not blink 164 | 165 | *TermitCursorShape* - one of those string values: 166 | 167 | * Block - Draw a block cursor 168 | * Ibeam - Draw a vertical bar on the left side of character 169 | * Underline - Draw a horizontal bar below the character 170 | 171 | *TermitEraseBinding* - one of those string values: 172 | 173 | * Auto - VTE_ERASE_AUTO 174 | * AsciiBksp - VTE_ERASE_ASCII_BACKSPACE 175 | * AsciiDel - VTE_ERASE_ASCII_DELETE 176 | * EraseDel - VTE_ERASE_DELETE_SEQUENCE 177 | * EraseTty - VTE_ERASE_TTY 178 | 179 | For detailed description look into Vte docs. 180 | 181 | *TermitKeybindings* - table with predefined keybindings. 182 | 183 | * closeTab - 'Ctrl-w' 184 | * copy - 'Ctrl-Insert' 185 | * nextTab - 'Alt-Right' 186 | * openTab - 'Ctrl-t' 187 | * paste - 'Shift-Insert' 188 | * prevTab - 'Alt-Left' 189 | 190 | pre. Example: enable Gnome-like tab switching 191 | keys = {} 192 | keys.nextTab = 'Ctrl-Page_Down' 193 | keys.prevTab = 'Ctrl-Page_Up' 194 | setKeys(keys) 195 | 196 | 197 | *TermitMenuItem* - table for menuitems. 198 | 199 | * accel - accelerator for menuitem. String with keybinding 200 | * action - lua-function to execute when item activated 201 | * name - name for menuitem 202 | 203 | 204 | *TermitOptions* - table with termit options. 205 | 206 | * allowChangingTitle - auto change title (similar to xterm) 207 | * audibleBell - enables audible bell 208 | * backgroundColor - background color 209 | * backspaceBinding - reaction on backspace key (one of TermitEraseBinding) 210 | * colormap - array with 8 or 16 or 24 colors 211 | * cursorBlinkMode - cursor blink mode (one of TermitCursorBlinkMode) 212 | * cursorShape - cursor shape (one of TermitCursorShape) 213 | * deleteBinding - reaction on delete key (one of TermitEraseBinding) 214 | * encoding - default encoding 215 | * fillTabbar - expand tabs' titles to fill whole tabbar 216 | * font - font name 217 | * foregroundColor - foreground color 218 | * geometry - cols x rows to start with 219 | * getTabTitle - lua function to generate new tab title 220 | * getWindowTitle - lua function to generate new window title 221 | * hideMenubar - hide menubar 222 | * hideTabbar - hide tabbar 223 | * hideSingleTab - hide tabbar when only 1 tab present 224 | * hideTitlebarWhenMaximized - hide window titlebar when mazimized 225 | * matches - table with items of TermitMatch type 226 | * scrollbackLines - the length of scrollback buffer 227 | * scrollOnKeystroke - enables scroll to the bottom when the user presses a key 228 | * scrollOnOutput - enables scroll to the bottom when new data is received 229 | * setStatusbar - lua function to generate new statusbar message 230 | * showBorder - show notebook border 231 | * showScrollbar - display scrollbar 232 | * startMaximized - maximize window on start 233 | * tabName - default tab name 234 | * tabPos - tabbar position (Top, Bottom, Left, Right) 235 | * tabs - table with items of TermitTabInfo type 236 | * urgencyOnBell - set WM-hint 'urgent' on termit window when bell 237 | * wordCharExceptions - additional word characters (double click selects word) 238 | 239 | 240 | *TermitTabInfo* - table with tab settings: 241 | 242 | * command 243 | * encoding 244 | * font - font string 245 | * fontSize - font size 246 | * pid - process id 247 | * title 248 | * workingDir 249 | 250 | 251 | h4. Globals 252 | 253 | *tabs* - Readonly table with tab settings, access specific tabs by index. 254 | 255 | 256 | h4. Bugs 257 | 258 | After start sometimes there is black screen. Resizing termit window helps. 259 | 260 | In options table 'tabs' field should be the last one. When loading all settings are applied in the same order as they are set in options table. So if you set tabs and only then colormap, these tabs would have default colormap. 261 | 262 | 263 | -------------------------------------------------------------------------------- /doc/rc.lua.example: -------------------------------------------------------------------------------- 1 | -- Example file with lots of options. 2 | -- You can test with with this command: 3 | -- cd ./etc && ../src/termit --init ../doc/rc.lua.example 4 | 5 | colormaps = require("termit.colormaps") 6 | utils = require("termit.utils") 7 | 8 | defaults = {} 9 | defaults.windowTitle = 'Termit' 10 | defaults.startMaximized = true 11 | defaults.hideTitlebarWhenMaximized = true 12 | defaults.tabName = 'Terminal' 13 | defaults.encoding = 'UTF-8' 14 | defaults.wordCharExceptions = '- .,_/' 15 | defaults.font = 'Terminus 12' 16 | --defaults.foregroundColor = 'gray' 17 | --defaults.backgroundColor = 'black' 18 | defaults.showScrollbar = true 19 | defaults.hideSingleTab = false 20 | defaults.hideTabbar = false 21 | defaults.showBorder = true 22 | defaults.hideMenubar = false 23 | defaults.fillTabbar = true 24 | defaults.scrollbackLines = 4096 25 | defaults.geometry = '80x24' 26 | defaults.allowChangingTitle = false 27 | --defaults.backspaceBinding = 'AsciiBksp' 28 | --defaults.deleteBinding = 'AsciiDel' 29 | defaults.cursorBlinkMode = 'BlinkOff' 30 | defaults.cursorShape = 'Ibeam' 31 | defaults.tabPos = 'Right' 32 | defaults.setStatusbar = function (tabInd) 33 | tab = tabs[tabInd] 34 | if tab then 35 | return tab.encoding..' Bksp: '..tab.backspaceBinding..' Del: '..tab.deleteBinding 36 | end 37 | return '' 38 | end 39 | defaults.colormap = colormaps.delicate 40 | defaults.matches = {['http[-:/.\\w]+'] = function (url) print('Matching url: '..url) end} 41 | defaults.tabs = {{title = 'Test new tab 1'; workingDir = '/tmp'}; 42 | {title = 'Test new tab 2'; workingDir = '/tmp'}} 43 | setOptions(defaults) 44 | 45 | bindKey('Ctrl-Page_Up', prevTab) 46 | bindKey('Ctrl-Page_Down', nextTab) 47 | bindKey('Ctrl-F', findDlg) 48 | bindKey('Ctrl-2', function () print('Hello2!') end) 49 | bindKey('Ctrl-3', function () print('Hello3!') end) 50 | bindKey('Ctrl-3', nil) -- remove previous binding 51 | 52 | -- don't close tab with Ctrl-w, use CtrlShift-w 53 | bindKey('Ctrl-w', nil) 54 | bindKey('CtrlShift-w', closeTab) 55 | 56 | setKbPolicy('keycode') 57 | 58 | bindMouse('DoubleClick', openTab) 59 | 60 | -- 61 | userMenu = {} 62 | table.insert(userMenu, {name='Close tab', action=closeTab}) 63 | table.insert(userMenu, {name='New tab name', action=function () setTabTitle('New tab name') end}) 64 | 65 | mi = {} 66 | mi.name = 'Zsh tab' 67 | mi.action = function () 68 | tabInfo = {} 69 | tabInfo.title = 'Zsh tab' 70 | tabInfo.command = 'zsh' 71 | tabInfo.encoding = 'UTF-8' 72 | tabInfo.workingDir = '/tmp' 73 | tabInfo.backspaceBinding = 'AsciiBksp' 74 | tabInfo.deleteBinding = 'EraseDel' 75 | openTab(tabInfo) 76 | end 77 | table.insert(userMenu, mi) 78 | 79 | table.insert(userMenu, {name='set red color', action=function () setTabForegroundColor('red') end}) 80 | table.insert(userMenu, {name='Reconfigure', action=reconfigure, accel='Ctrl-r'}) 81 | table.insert(userMenu, {name='Selection', action=function () print(selection()) end}) 82 | table.insert(userMenu, {name='dumpAllRows', action=function () forEachRow(print) end}) 83 | table.insert(userMenu, {name='dumpVisibleRowsToFile', 84 | action=function () utils.dumpToFile(forEachVisibleRow, '/tmp/termit.dump') end}) 85 | table.insert(userMenu, {name='findNext', action=findNext, accel='Alt-n'}) 86 | table.insert(userMenu, {name='findPrev', action=findPrev, accel='Alt-p'}) 87 | table.insert(userMenu, {name='new colormap', action=function () setColormap(colormaps.mikado) end}) 88 | table.insert(userMenu, {name='toggle menubar', action=function () toggleMenubar() end}) 89 | table.insert(userMenu, {name='toggle tabbar', action=function () toggleTabbar() end}) 90 | 91 | mi = {} 92 | mi.name = 'Get tab info' 93 | mi.action = function () 94 | tab = tabs[currentTabIndex()] 95 | if tab then 96 | utils.printTable(tab, ' ') 97 | end 98 | end 99 | table.insert(userMenu, mi) 100 | 101 | function round(float) 102 | return math.floor(float + .5) 103 | end 104 | 105 | function changeTabFontSize(delta) 106 | tab = tabs[currentTabIndex()] 107 | fontSize = round(tab.fontSize) 108 | setTabFont(string.sub(tab.font, 1, string.find(tab.font, '%d+$') - 1)..(fontSize + delta)) 109 | end 110 | 111 | table.insert(userMenu, {name='Increase font size', action=function () changeTabFontSize(1) end}) 112 | table.insert(userMenu, {name='Decrease font size', action=function () changeTabFontSize(-1) end}) 113 | table.insert(userMenu, {name='feed example', action=function () feed('example') end}) 114 | table.insert(userMenu, {name='feedChild example', action=function () feedChild('date\n') end}) 115 | table.insert(userMenu, {name='move tab left', action=function () setTabPos(currentTabIndex() - 1) end}) 116 | table.insert(userMenu, {name='move tab right', action=function () setTabPos(currentTabIndex() + 1) end}) 117 | table.insert(userMenu, {name='User quit', action=quit}) 118 | 119 | addMenu(userMenu, "User menu") 120 | addPopupMenu(userMenu, "User menu") 121 | 122 | addMenu(utils.encMenu(), "Encodings") 123 | addPopupMenu(utils.encMenu(), "Encodings") 124 | 125 | -------------------------------------------------------------------------------- /doc/termit.1: -------------------------------------------------------------------------------- 1 | .\" Process this file with 2 | .\" groff -man -Tascii foo.1 3 | .\" 4 | .TH TERMIT 1 "NOV 2008" Linux "User Manuals" 5 | .SH NAME 6 | termit \(hy lightweight terminal emulator 7 | .SH SYNOPSIS 8 | .B termit [\-option ...] 9 | .SH DESCRIPTION 10 | .B termit 11 | is a vte\(hybased lightweight terminal emulator. All configuration 12 | is done via Lua\(hyscripts. The only other dependencies are 13 | Gtk+ and Vte. 14 | .SH OPTIONS 15 | .BR \-h, 16 | .BR \-\-help 17 | .RS 18 | Print help 19 | .RE 20 | .BR \-v, 21 | .BR \-\-version 22 | .RS 23 | Print version number 24 | .RE 25 | .BR \-e, 26 | .BR \-\-execute 27 | = 28 | .I cmd 29 | .RS 30 | Use 31 | .I cmd 32 | as shell 33 | .RE 34 | .BR \-i, 35 | .BR \-\-init 36 | = 37 | .I file 38 | .RS 39 | Use 40 | .I file 41 | instead of default rc.lua 42 | .RE 43 | .BR \-n, 44 | .BR \-\-name 45 | = 46 | .I name 47 | .RS 48 | Use 49 | .I name 50 | in window name hint 51 | .RE 52 | .BR \-c, 53 | .BR \-\-class 54 | = 55 | .I class 56 | .RS 57 | Use 58 | .I class 59 | in window class hint 60 | .RE 61 | .BR \-r, 62 | .BR \-\-role 63 | = 64 | .I role 65 | .RS 66 | Use 67 | .I role 68 | in window role Gtk\(hyhint 69 | .RE 70 | .BR \-T, 71 | .BR \-\-title 72 | = 73 | .I title 74 | .RS 75 | Use 76 | .I title 77 | in window title (Turns off 78 | .I allowChangingTitle 79 | option.) 80 | .RE 81 | .P 82 | termit \-\-init=session.lua \-\-name=TermitName \-\-class=TermitClass \-\-role=TermitRole \-\-title=TermitTitle \-\-execute=zsh 83 | .P 84 | .RE 85 | .SH FILES 86 | .I $HOME/.config/termit/rc.lua 87 | .RS 88 | Per user configuration file. See section 89 | .BR "TERMIT LUA API" 90 | for further details. 91 | .RE 92 | .I /usr/share/doc/termit/rc.lua.example 93 | .RS 94 | Example rc.lua file. Demonstrates usage of almost all available settings. 95 | .SH "TERMIT LUA API" 96 | .B "Functions:" 97 | 98 | .B activateTab 99 | ( 100 | .I tab_index 101 | ) 102 | Activates tab by index. 103 | tab_index \(hy index of tab to activate. Index of the first tab is 1. 104 | .P 105 | .B addMenu 106 | ( 107 | .I menu 108 | ) 109 | Adds menu in menubar. 110 | menu \(hy table of TermitMenuItem type. 111 | .P 112 | .B addPopupMenu 113 | ( 114 | .I menu 115 | ) 116 | Adds menu in popup menu, similar to addMenu. 117 | menu \(hy table of TermitMenuItem type. 118 | .P 119 | .B bindKey 120 | ( 121 | .I keys 122 | , 123 | .I luaFunction 124 | ) 125 | Sets new keybinding. If luaFunction is 126 | .I nil 127 | removes keybinding. 128 | keys \(hy string with keybinding. Available modifiers are Alt Ctrl Shift Meta Super Hyper. 129 | luaFunction \(hy callback function 130 | .P 131 | .B bindMouse 132 | ( 133 | .I event 134 | , 135 | .I luaFunction 136 | ) 137 | Sets new mouse\(hybinding. If luaFunction is 138 | .I nil 139 | removes mouse\(hybinding. 140 | event \(hy string with one of those values: DoubleClick 141 | luaFunction \(hy callback function 142 | .P 143 | .B closeTab 144 | () 145 | Closes active tab. 146 | .P 147 | .B copy 148 | () 149 | Copies selection into tab's buffer. 150 | .P 151 | .B currentTab 152 | () 153 | Returns current tab of TermitTabInfo. 154 | .P 155 | .B currentTabIndex 156 | () 157 | Returns current tab index. 158 | .P 159 | .B feed 160 | ( 161 | .I 162 | data 163 | ) 164 | Interprets data as if it were data received from a terminal process. 165 | .P 166 | .B feedChild 167 | ( 168 | .I 169 | data 170 | ) 171 | Sends a data to the terminal as if it were data entered by the user at the keyboard. 172 | .P 173 | .B findDlg 174 | () 175 | Opens search entry. 176 | .P 177 | .B findNext 178 | () 179 | Searches the next string matching search regex. 180 | .P 181 | .B findPrev 182 | () 183 | Searches the previous string matching search regex. 184 | .P 185 | .B forEachRow 186 | ( 187 | .I func 188 | ) 189 | For each terminal row in entire scrollback buffer executes function passing row as argument. 190 | func \(hy function to be called. 191 | .P 192 | .B forEachVisibleRow 193 | ( 194 | .I func 195 | ) 196 | For each visible terminal row executes function passing row as argument. 197 | func \(hy function to be called. 198 | .P 199 | .B loadSessionDlg 200 | () 201 | Displays "Load session" dialog. 202 | .P 203 | .B nextTab 204 | () 205 | Activates next tab. 206 | .P 207 | .B openTab 208 | ( 209 | .I tabInfo 210 | ) 211 | Opens new tab. 212 | tabinfo \(hy table of TermitTabInfo with tab settings. 213 | .P 214 | .B paste 215 | () 216 | Pastes tab's buffer. 217 | .P 218 | .B preferencesDlg 219 | () 220 | Displays "Preferences" dialog. 221 | .P 222 | .B prevTab 223 | () 224 | Activates previous tab. 225 | .P 226 | .B quit 227 | () 228 | Quit. 229 | .P 230 | .B reconfigure 231 | () 232 | Sets all configurable variables to defaults and forces rereading rc.lua. 233 | .P 234 | .B saveSessionDlg 235 | () 236 | Displays "Save session" dialog. 237 | .P 238 | .B selection 239 | () 240 | Returns selected text from current tab. 241 | .P 242 | .B setColormap 243 | ( 244 | .I colormap 245 | ) 246 | Changes colormap for active tab. 247 | colormap \(hy array with 8 or 16 or 24 colors. 248 | .P 249 | .B setEncoding 250 | ( 251 | .I encoding 252 | ) 253 | Changes encoding for active tab. 254 | encoding \(hy string with encoding name. 255 | .P 256 | .B setKbPolicy 257 | ( 258 | .I kb_policy 259 | ) 260 | Sets keyuboard policy for shortcuts. 261 | kb_policy \(hy string with one of those values: 262 | keycode \(hy use hardware keyboard codes (XkbLayout\(hyindependent) 263 | keysym \(hy use keysym values (XkbLayout\(hydependent) 264 | .P 265 | .B setOptions 266 | ( 267 | .I opts 268 | ) 269 | Changes default options. 270 | opts \(hy TermitOptions table with new options. 271 | .P 272 | .B setTabBackgroundColor 273 | ( 274 | .I color 275 | ) 276 | Changes background color for active tab. 277 | color \(hy string with new color. 278 | .P 279 | .B setTabFont 280 | ( 281 | .I font 282 | ) 283 | Changes font for active tab. 284 | font \(hy string with new font. 285 | .P 286 | .B setTabForegroundColor 287 | ( 288 | .I color 289 | ) 290 | Changes foreground (e.g. font) color for active tab. 291 | color \(hy string with new color. 292 | .P 293 | .B setTabPos 294 | ( 295 | .I newPos 296 | ) 297 | Changes position for active tab. 298 | newPos \(hy number with new tab position. 299 | .P 300 | .B setTabTitle 301 | ( 302 | .I tabTitle 303 | ) 304 | Changes title for active tab. 305 | tabTitle \(hy string with new tab title. 306 | .P 307 | .B setTabTitleDlg 308 | () 309 | Displays "Set tab title" dialog. 310 | .P 311 | .B setWindowTitle 312 | ( 313 | .I title 314 | ) 315 | Changes termit window title. 316 | title \(hy string with new title. 317 | .P 318 | .B spawn 319 | ( 320 | .I command 321 | ) 322 | Spawns command (works via shell). 323 | command \(hy string with command and arguments. 324 | .P 325 | .B toggleMenubar 326 | () 327 | Displays or hides menubar. 328 | .P 329 | .P 330 | .B toggleTabbar 331 | () 332 | Displays or hides tabbar. 333 | .P 334 | 335 | .B "Types:" 336 | 337 | .B TermitCursorBlinkMode 338 | \(hy one of those string values: 339 | System Follow GTK+ settings for cursor blinking 340 | BlinkOn Cursor blinks 341 | BlinkOff Cursor does not blink 342 | .P 343 | .B TermitCursorShape 344 | \(hy one of those string values: 345 | Block Draw a block cursor 346 | Ibeam Draw a vertical bar on the left side of character 347 | Underline Draw a horizontal bar below the character 348 | .P 349 | .B TermitEraseBinding 350 | \(hy one of those string values: 351 | Auto VTE_ERASE_AUTO 352 | AsciiBksp VTE_ERASE_ASCII_BACKSPACE 353 | AsciiDel VTE_ERASE_ASCII_DELETE 354 | EraseDel VTE_ERASE_DELETE_SEQUENCE 355 | EraseTty VTE_ERASE_TTY 356 | .P 357 | For detailed description look into Vte docs. 358 | .P 359 | .B TermitKeybindings 360 | \(hy table with predefined keybindings. 361 | closeTab 'Ctrl\(hyw' 362 | copy 'Ctrl\(hyInsert' 363 | nextTab 'Alt\(hyRight' 364 | openTab 'Ctrl\(hyt' 365 | paste 'Shift\(hyInsert' 366 | prevTab 'Alt\(hyLeft' 367 | .P 368 | .B TermitMatch 369 | \(hy table for matches. 370 | field name match regular expression 371 | field value lua callback for action on Left\(hyclick. 372 | .P 373 | .B TermitMenuItem 374 | \(hy table for menuitems. 375 | accel accelerator for menuitem. String with keybinding 376 | action lua function to execute when item activated 377 | name name for menuitem 378 | .P 379 | .B TermitOptions 380 | \(hy table with termit options. 381 | allowChangingTitle auto change title (similar to xterm) 382 | audibleBell enables audible bell 383 | backgroundColor background color 384 | backspaceBinding reaction on backspace key (one of TermitEraseBinding) 385 | colormap array with 8 or 16 or 24 colors 386 | cursorBlinkMode cursor blink mode (one of TermitCursorBlinkMode) 387 | cursorShape cursor shape (one of TermitCursorShape) 388 | deleteBinding reaction on delete key (one of TermitEraseBinding) 389 | encoding default encoding 390 | fillTabbar expand tabs' titles to fill whole tabbar 391 | font font name 392 | foregroundColor foreground color 393 | geometry cols x rows to start with 394 | getTabTitle lua function to generate new tab title 395 | getWindowTitle lua function to generate new window title 396 | hideMenubar hide menubar 397 | hideSingleTab hide tabbar when only 1 tab present 398 | hideTabbar hide tabbar 399 | hideTitlebarWhenMaximized hide window titlebar when mazimized 400 | matches table with items of TermitMatch type 401 | scrollbackLines the length of scrollback buffer 402 | scrollOnKeystroke enables scroll to the bottom when the user presses a key 403 | scrollOnOutput enables scroll to the bottom when new data is received 404 | setStatusbar lua function to generate new statusbar message 405 | showScrollbar display scrollbar 406 | showBorder show notebook borders 407 | startMaximized maximize window on start 408 | tabName default tab name 409 | tabPos tabbar position (Top, Bottom, Left, Right) 410 | tabs table with items of TermitTabInfo type 411 | urgencyOnBell set WM\(hyhint 'urgent' on termit window when bell 412 | wordCharExceptions additional word characters (double click selects word) 413 | .P 414 | .B TermitTabInfo 415 | \(hy table with tab settings: 416 | command tab start command 417 | encoding current tab encoding 418 | font font string 419 | fontSize font size 420 | pid process id 421 | title tab title 422 | workingDir tab working dir 423 | .P 424 | .B "Globals:" 425 | 426 | .B tabs 427 | is the array with settings for all tabs. Access specific tab by index. 428 | .RS 429 | .SH EXAMPLES 430 | Look inside provided rc.lua.example. 431 | .SH BUGS 432 | After start sometimes there is black screen. Resizing termit window helps. 433 | .P 434 | In options table 'tabs' field should be the last one. When loading all settings are applied in the same order as they are set in options table. So if you set tabs and only then colormap, these tabs would have default colormap. 435 | .SH AUTHOR 436 | Evgeny Ratnikov 437 | .SH "SEE ALSO" 438 | .BR lua (1) 439 | -------------------------------------------------------------------------------- /doc/termit.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Termit 3 | GenericName=Terminal emulator 4 | GenericName[ru]=Эмулятор терминала 5 | Comment=Lightweight terminal emulator 6 | Comment[ru]=Легкий эмулятор терминала 7 | TryExec=termit 8 | Exec=termit 9 | Icon=utilities-terminal 10 | Type=Application 11 | Categories=GTK;System;TerminalEmulator; 12 | Terminal=false 13 | Keywords=Run; 14 | 15 | -------------------------------------------------------------------------------- /doc/termit.metainfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.gnome.ratnikov.ev.apps.termit 5 | FSFAP 6 | GPL-3.0+ 7 | Termit 8 | Terminal emulator 9 | 10 | 11 | Small terminal emulator configurable via Lua. 12 | Other dependencies are Vte and Gtk3 libs. 13 | Termit supports multiple tabs, encoding switching and sessions. 14 | 15 | 16 | termit.desktop 17 | 18 | 19 | Terminal main window with shell session 20 | https://raw.githubusercontent.com/nonstop/termit/master/doc/termit.png 21 | 22 | 23 | https://github.com/nonstop/termit/wiki 24 | GNOME 25 | 26 | termit 27 | 28 | Evgeny Ratnikov 29 | https://github.com/nonstop/termit/issues 30 | 31 | -------------------------------------------------------------------------------- /doc/termit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonstop/termit/805e00a5457b665f4e7ab695c903f8fed8662c17/doc/termit.png -------------------------------------------------------------------------------- /doc/termit.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 25 | 26 | 27 | 29 | 30 | 2.0 31 | 32 | 33 | 34 | TermIt 35 | 36 | 37 | terminal emulator 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /etc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright © 2007-2023 Evgeny Ratnikov 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | SET(TERMIT_ETC termit/rc.lua termit/colormaps.lua termit/utils.lua) 17 | 18 | INSTALL(FILES ${TERMIT_ETC} DESTINATION ${TERMIT_XDG_DIR}) 19 | 20 | -------------------------------------------------------------------------------- /etc/termit/colormaps.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.tango = {'#2e2e34343636', '#cccc00000000', '#4e4e9a9a0606', '#c4c4a0a00000', '#34346565a4a4', '#757550507b7b', '#060698209a9a', '#d3d3d7d7cfcf', '#555557575353', '#efef29292929', '#8a8ae2e23434', '#fcfce9e94f4f', '#72729f9fcfcf', '#adad7f7fa8a8', '#3434e2e2e2e2', '#eeeeeeeeecec'} 4 | M.zenburn = {'#1e2320', '#705050', '#60b48a', '#dfaf8f', '#b8c2cb', '#dc8cc3', '#486858', '#dcdccc', '#709080' ,'#dca3a3', '#c3bf9f', '#f0dfaf', '#94bff3', '#ec93d3', '#93e0e3', '#ffffff'} 5 | M.delicate = {'#2B2B2B', '#870000', '#5F875F', '#875F00', '#005FAF', '#5F5F87', '#008787', '#818181', '#414141', '#D70000', '#AFD7AF', '#D7AF00', '#00AFFF', '#AFAFD7', '#00D7D7', '#CECECE'} 6 | M.mikado = {'#322a2c', '#a04363', '#9b9329', '#bf7a29', '#6a8c8c', '#856774', '#757978', '#bcbcaf', '#46423b', '#ae837a', '#b4aa30', '#c7a551', '#74999e', '#9c818e', '#9fa590', '#c1c4bc'} 7 | M.parkerBrothers = {'#322a2c', '#79220E', '#344B1B', '#B45B00', '#434045', '#5C1E25', '#394745', '#AE8842', '#46423b', '#AA261F', '#76550F', '#B57F02', '#908862', '#624A35', '#393E38', '#A59058'} 8 | M.fishbone = {'#293b3b', '#bf5357', '#41a551', '#aea64f', '#416ea5', '#bf6053', '#714da5', '#876868', '#344040', '#bf6367', '#51a55f', '#aea75d', '#5177a5', '#bf6e63', '#7859a5', '#876f6f'} 9 | M.bright = {'#000000', '#CD0000', '#00CD00', '#CDCD00', '#0000CD', '#CD00CD', '#00CDCD', '#E5E5E5', '#4D4D4D', '#ff0000', '#00ff00', '#00ffff', '#0000ff', '#ff00ff', '#00ffff', '#ffffff'} 10 | M.irc = {'#000000', '#800000', '#008000', '#FF8000', '#000080', '#800080', '#408080', '#C0C0C0', '#808080', '#FF0000', '#00FF00', '#FFFF00', '#0000FF', '#FF00FF', '#00FFFF', '#FFFFFF'} 11 | M.gruvboxDark = {'#282828', '#cc241d', '#98971a', '#d79921', '#458588', '#b16286', '#689d6a', '#a89984', '#928374', '#fb4934', '#b8bb26', '#fabd2f', '#83a598', '#d3869b', '#8ec07c', '#ebdbb2'} 12 | M.gruvboxLight = {'#fbf1c7', '#cc241d', '#98971a', '#d79921', '#458588', '#b16286', '#689d6a', '#7c6f64', '#928374', '#9d0006', '#79740e', '#b57614', '#076678', '#8f3f71', '#427b58', '#3c3836'} 13 | 14 | return M 15 | -------------------------------------------------------------------------------- /etc/termit/rc.lua: -------------------------------------------------------------------------------- 1 | colormaps = require('termit.colormaps') 2 | utils = require('termit.utils') 3 | 4 | defaults = {} 5 | defaults.windowTitle = 'Termit' 6 | defaults.tabName = 'Terminal' 7 | defaults.encoding = 'UTF-8' 8 | defaults.scrollbackLines = 4096 9 | defaults.font = 'Monospace 10' 10 | defaults.geometry = '80x24' 11 | defaults.hideSingleTab = false 12 | defaults.showScrollbar = true 13 | defaults.fillTabbar = false 14 | defaults.hideMenubar = false 15 | defaults.allowChangingTitle = false 16 | defaults.audibleBell = false 17 | defaults.urgencyOnBell = false 18 | setOptions(defaults) 19 | 20 | setKbPolicy('keysym') 21 | -------------------------------------------------------------------------------- /etc/termit/utils.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local io = io 3 | local pairs, print = pairs, print 4 | local table, tostring, type = table, tostring, type 5 | local setEncoding = setEncoding 6 | 7 | function encMenu () 8 | encodings = {'UTF-8', 'KOI8-R', 'CP1251', 'CP866'} 9 | menu = {} 10 | for k, v in pairs(encodings) do 11 | table.insert(menu, {name = v; action = function () setEncoding(v) end}) 12 | end 13 | return menu 14 | end 15 | 16 | function pairsByKeys(t, f) 17 | local a = {} 18 | for n in pairs(t) do table.insert(a, n) end 19 | table.sort(a, f) 20 | local i = 0 -- iterator variable 21 | local iter = function () -- iterator function 22 | i = i + 1 23 | if a[i] == nil then return nil 24 | else return a[i], t[a[i]] 25 | end 26 | end 27 | return iter 28 | end 29 | 30 | function printTable(tbl, indent) 31 | for k, v in pairsByKeys(tbl) do 32 | if type(v) == 'table' then 33 | print(indent..k..':') 34 | local_indent = indent..' ' 35 | printTable(v, local_indent) 36 | else 37 | print(indent..tostring(k)..'='..tostring(v)) 38 | end 39 | end 40 | end 41 | 42 | function dumpToFile(func, file) 43 | io.output(io.open(file, 'w+')) 44 | callback = function (str) io.write(str..'\n') end 45 | func(callback) 46 | io.close() 47 | end 48 | 49 | M.encMenu = encMenu 50 | M.pairsByKeys = pairsByKeys 51 | M.printTable = printTable 52 | M.dumpToFile = dumpToFile 53 | 54 | return M 55 | -------------------------------------------------------------------------------- /po/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(PO_FILES 2 | ca.po 3 | da.po 4 | de.po 5 | es.po 6 | fr.po 7 | hu.po 8 | ja.po 9 | ko.po 10 | nl.po 11 | pl.po 12 | ru.po 13 | sv.po 14 | zh_TW.po) 15 | 16 | SET(COPYRIGHT_HOLDER "Evgeny Ratnikov") 17 | SET(POT_FILE termit.pot) 18 | 19 | INCLUDE(${TERMIT_SOURCE_DIR}/src/Sources.cmake) 20 | 21 | FIND_PROGRAM(XGETTEXT_EXECUTABLE xgettext) 22 | FIND_PROGRAM(MSGFMT_EXECUTABLE msgfmt) 23 | FIND_PROGRAM(MSGMERGE_EXECUTABLE msgmerge) 24 | SET(ENABLE_NLS FALSE) 25 | IF(XGETTEXT_EXECUTABLE AND MSGFMT_EXECUTABLE AND MSGMERGE_EXECUTABLE) 26 | SET(ENABLE_NLS TRUE) 27 | ENDIF(XGETTEXT_EXECUTABLE AND MSGFMT_EXECUTABLE AND MSGMERGE_EXECUTABLE) 28 | IF(NOT ENABLE_NLS) 29 | MESSAGE(SEND_ERROR "gettext utils not found, disabling gettext") 30 | ELSE(NOT ENABLE_NLS) 31 | # Create PO Template file 'termit.pot' 32 | SET(PO_SOURCE_FILES) 33 | SET(PO_SOURCE_FILES_FULL_PATH) 34 | FOREACH(SRC_FILE ${TERMIT_SRCS}) 35 | SET(PO_SOURCE_FILES ${PO_SOURCE_FILES} src/${SRC_FILE}) 36 | SET(PO_SOURCE_FILES_FULL_PATH ${PO_SOURCE_FILES_FULL_PATH} ${TERMIT_SOURCE_DIR}/src/${SRC_FILE}) 37 | ENDFOREACH(SRC_FILE ${TERMIT_SRCS}) 38 | 39 | ADD_CUSTOM_COMMAND( 40 | OUTPUT ${POT_FILE} 41 | COMMAND ${XGETTEXT_EXECUTABLE} 42 | ARGS -o ${POT_FILE} -s --directory=${TERMIT_SOURCE_DIR} --omit-header --msgid-bugs-address=${TERMIT_PACKAGE_BUGREPORT} -c --keyword=_ --copyright-holder=${COPYRIGHT_HOLDER} ${PO_SOURCE_FILES} 43 | DEPENDS ${PO_SOURCE_FILES_FULL_PATH}) 44 | ADD_CUSTOM_TARGET(pot DEPENDS ${PO_SOURCE_FILES_FULL_PATH} ${POT_FILE}) 45 | 46 | # Update .po files and compile them into .gmo files 47 | SET(GMO_FILES) 48 | FOREACH(PO_FILE ${PO_FILES}) 49 | GET_FILENAME_COMPONENT(LANG ${PO_FILE} NAME_WE) 50 | SET(_gmofile ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo) 51 | ADD_CUSTOM_COMMAND( 52 | OUTPUT ${_gmofile} 53 | COMMAND ${MSGMERGE_EXECUTABLE} ARGS --quiet --update -s ${CMAKE_CURRENT_SOURCE_DIR}/${PO_FILE} ${POT_FILE} 54 | COMMAND ${MSGFMT_EXECUTABLE} ARGS -o ${_gmofile} ${CMAKE_CURRENT_SOURCE_DIR}/${PO_FILE} 55 | DEPENDS ${POT_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/${PO_FILE} 56 | COMMENT "Language: ${LANG}") 57 | INSTALL(FILES ${_gmofile} DESTINATION ${TERMIT_LOCALE_DIR}/${LANG}/LC_MESSAGES RENAME termit.mo) 58 | SET(GMO_FILES ${GMO_FILES} ${_gmofile}) 59 | ENDFOREACH(PO_FILE ${PO_FILES}) 60 | 61 | ADD_CUSTOM_TARGET(gmo ALL DEPENDS ${GMO_FILES}) 62 | ADD_DEPENDENCIES(gmo pot) 63 | 64 | SET(TERMIT_DISTR_FILES "${POT_FILE} ${PO_FILES} CMakeLists.txt") 65 | ENDIF(NOT ENABLE_NLS) 66 | 67 | -------------------------------------------------------------------------------- /po/ca.po: -------------------------------------------------------------------------------- 1 | # Termit translation file. 2 | # Copyright (C) 2025 3 | # This file is distributed under the same license as the termit package. 4 | # Evgeny Ratnikov ratnikov.ev@gmail.com 2025. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "POT-Creation-Date: \n" 10 | "PO-Revision-Date: 2025-01-01 13:13+0100\n" 11 | "Last-Translator: SwissalpS \n" 12 | "Language-Team: \n" 13 | "Language: Catalan\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | 18 | #: src/termit_preferences.c:219 19 | msgid "Apply to all tabs" 20 | msgstr "Aplica a totes les pestanyes" 21 | 22 | #: src/termit_preferences.c:213 23 | #, fuzzy 24 | msgid "Audible bell" 25 | msgstr "Campana audible" 26 | 27 | #: src/termit_preferences.c:207 28 | msgid "Background" 29 | msgstr "Fons" 30 | 31 | #: src/termit_core_api.c:464 32 | msgid "Cannot create a new tab" 33 | msgstr "No es pot crear una pestanya nova" 34 | 35 | #: src/termit_core_api.c:416 36 | msgid "Cannot parse command. Creating tab with shell" 37 | msgstr "No es pot analitzar l'ordre. Creant pestanya amb shell" 38 | 39 | #: src/termit.c:170 src/termit.c:223 40 | msgid "Close tab" 41 | msgstr "Tanca la pestanya" 42 | 43 | #: src/termit.c:187 src/termit.c:226 44 | msgid "Copy" 45 | msgstr "Còpia" 46 | 47 | #: src/termit.c:190 48 | msgid "Edit" 49 | msgstr "Edita" 50 | 51 | #: src/termit.c:173 52 | msgid "File" 53 | msgstr "Fitxer" 54 | 55 | #: src/termit_preferences.c:193 56 | msgid "Font" 57 | msgstr "Tipus de lletra" 58 | 59 | #: src/termit_preferences.c:200 60 | msgid "Foreground" 61 | msgstr "Primer pla" 62 | 63 | #. File menu 64 | #: src/termit.c:169 src/termit.c:222 65 | msgid "New tab" 66 | msgstr "Pestanya nova" 67 | 68 | #. Sessions menu 69 | #: src/termit.c:202 src/callbacks.c:418 70 | msgid "Open session" 71 | msgstr "Obrir sessió" 72 | 73 | #: src/termit.c:188 src/termit.c:227 74 | msgid "Paste" 75 | msgstr "Enganxa" 76 | 77 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 78 | msgid "Preferences" 79 | msgstr "Preferències" 80 | 81 | #: src/termit.c:171 src/termit.c:228 82 | msgid "Quit" 83 | msgstr "Surt" 84 | 85 | #: src/termit.c:203 src/callbacks.c:388 86 | msgid "Save session" 87 | msgstr "Guarda la sessió" 88 | 89 | #: src/termit.c:229 90 | msgid "Scrollbar" 91 | msgstr "Barra de desplaçament" 92 | 93 | #: src/termit.c:205 94 | msgid "Sessions" 95 | msgstr "Sessions" 96 | 97 | #. Edit menu 98 | #: src/termit.c:185 src/termit.c:224 99 | msgid "Set tab name..." 100 | msgstr "Estableix el nom de la pestanya..." 101 | 102 | #: src/callbacks.c:41 103 | msgid "" 104 | "Several tabs are opened.\n" 105 | "Close anyway?" 106 | msgstr "" 107 | "Hi ha pestanyes obertes.\n" 108 | "Tancar de totes maneres?" 109 | 110 | #: src/callbacks.c:297 src/callbacks.c:308 111 | msgid "Tab name" 112 | msgstr "Nom de la pestanya" 113 | 114 | #: src/termit_preferences.c:187 115 | msgid "Title" 116 | msgstr "Titol" 117 | 118 | #: src/sessions.c:90 119 | #, c-format 120 | msgid "Unable to create directory '%s': %s" 121 | msgstr "No es pot crear el directori '%s': %s" 122 | 123 | #~ msgid "Background image" 124 | #~ msgstr "Imatge de fons" 125 | 126 | #~ msgid "Image" 127 | #~ msgstr "Imatge" 128 | 129 | #~ msgid "Transparency" 130 | #~ msgstr "Transparència" 131 | 132 | #~ msgid "Visible bell" 133 | #~ msgstr "Campana visible" 134 | 135 | #~ msgid "images" 136 | #~ msgstr "imatges" 137 | 138 | -------------------------------------------------------------------------------- /po/da.po: -------------------------------------------------------------------------------- 1 | # Termit translation file. 2 | # Copyright (C) 2025 3 | # This file is distributed under the same license as the termit package. 4 | # Evgeny Ratnikov ratnikov.ev@gmail.com 2025. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "POT-Creation-Date: \n" 10 | "PO-Revision-Date: 2025-01-02 10:50+0100\n" 11 | "Last-Translator: SwissalpS \n" 12 | "Language-Team: \n" 13 | "Language: Danish\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | 18 | #: src/termit_preferences.c:299 19 | msgid "Audible bell" 20 | msgstr "Hørbar klokke" 21 | 22 | #: src/termit_preferences.c:260 23 | msgid "Background" 24 | msgstr "Baggrund" 25 | 26 | #: src/termit_preferences.c:276 27 | msgid "Background image" 28 | msgstr "Baggrunds billede" 29 | 30 | #: src/termit_core_api.c:433 31 | msgid "Cannot create a new tab" 32 | msgstr "Kan ikke oprette ny fane" 33 | 34 | #: src/termit_core_api.c:361 35 | msgid "Cannot parse command. Creating tab with shell" 36 | msgstr "Kan ikke tolke kommando. Opretter fane med skal" 37 | 38 | #: src/termit.c:194 39 | msgid "Edit" 40 | msgstr "Redigér" 41 | 42 | #: src/termit.c:177 43 | msgid "File" 44 | msgstr "Fil" 45 | 46 | #: src/termit_preferences.c:242 47 | msgid "Font" 48 | msgstr "Skrifttype" 49 | 50 | #: src/termit_preferences.c:251 51 | msgid "Foreground" 52 | msgstr "Forgrund" 53 | 54 | #. g_signal_connect(btn_switch_image_file, "toggled", G_CALLBACK(dlg_switch_image_file), btn_image_file); 55 | #. TERMIT_PREFERENCE_ROW2(btn_switch_image_file, btn_image_file); 56 | #: src/termit_preferences.c:283 57 | msgid "Image" 58 | msgstr "Billede" 59 | 60 | #: src/callbacks.c:383 61 | msgid "Open session" 62 | msgstr "Åben session" 63 | 64 | #: src/callbacks.c:353 65 | msgid "Save session" 66 | msgstr "Gem session" 67 | 68 | #: src/termit.c:234 69 | msgid "Scrollbar" 70 | msgstr "Rullebjælke" 71 | 72 | #: src/termit.c:209 73 | msgid "Sessions" 74 | msgstr "Sessioner" 75 | 76 | #. Edit menu 77 | #: src/termit.c:189 src/termit.c:229 78 | msgid "Set tab name..." 79 | msgstr "Angiv fanenavn..." 80 | 81 | #: src/callbacks.c:37 82 | msgid "" 83 | "Several tabs are opened.\n" 84 | "Close anyway?" 85 | msgstr "" 86 | "Adskillige faner åbne.\n" 87 | "Luk alligevel?" 88 | 89 | #: src/callbacks.c:262 src/callbacks.c:271 90 | msgid "Tab name" 91 | msgstr "Fanenavn" 92 | 93 | #: src/termit_preferences.c:235 94 | msgid "Title" 95 | msgstr "Titel" 96 | 97 | #: src/termit_preferences.c:291 98 | msgid "Transparency" 99 | msgstr "Gennemsigtighed" 100 | 101 | #: src/sessions.c:90 102 | #, c-format 103 | msgid "Unable to create directory '%s': %s" 104 | msgstr "Kan ikke oprette sti '%s': %s" 105 | 106 | #: src/termit_preferences.c:307 107 | msgid "Visible bell" 108 | msgstr "Synlige klokke" 109 | 110 | #: src/termit_preferences.c:267 111 | msgid "images" 112 | msgstr "billeder" 113 | 114 | -------------------------------------------------------------------------------- /po/de.po: -------------------------------------------------------------------------------- 1 | # Termit translation file. 2 | # Copyright (C) 2007 3 | # This file is distributed under the same license as the termit package. 4 | # Evgeny Ratnikov ratnikov.ev@gmail.com 2007. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: 1.0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: \n" 11 | "PO-Revision-Date: 2022-09-08 22:22+0100\n" 12 | "Last-Translator: SwissalpS \n" 13 | "Language-Team: de\n" 14 | "Language: \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #: src/termit_preferences.c:219 20 | msgid "Apply to all tabs" 21 | msgstr "Auf alle Tabs anwenden" 22 | 23 | #: src/termit_preferences.c:213 24 | #, fuzzy 25 | msgid "Audible bell" 26 | msgstr "Glocke" 27 | 28 | #: src/termit_preferences.c:207 29 | msgid "Background" 30 | msgstr "Hintergrund" 31 | 32 | #: src/termit_core_api.c:464 33 | msgid "Cannot create a new tab" 34 | msgstr "Konnte keinen neuen Tab erzeugen" 35 | 36 | #: src/termit_core_api.c:416 37 | msgid "Cannot parse command. Creating tab with shell" 38 | msgstr "" 39 | "Konnte Befehl nicht untersuchen. Erstelle einen Tab mit der Kommandozeile" 40 | 41 | #: src/termit.c:170 src/termit.c:223 42 | msgid "Close tab" 43 | msgstr "Tab schliessen" 44 | 45 | #: src/termit.c:187 src/termit.c:226 46 | msgid "Copy" 47 | msgstr "Kopieren" 48 | 49 | #: src/termit.c:190 50 | msgid "Edit" 51 | msgstr "Bearbeiten" 52 | 53 | #: src/termit.c:173 54 | msgid "File" 55 | msgstr "Datei" 56 | 57 | #: src/termit_preferences.c:193 58 | msgid "Font" 59 | msgstr "Schriftart" 60 | 61 | #: src/termit_preferences.c:200 62 | msgid "Foreground" 63 | msgstr "Vordergrund" 64 | 65 | #. File menu 66 | #: src/termit.c:169 src/termit.c:222 67 | msgid "New tab" 68 | msgstr "Neuen Tab" 69 | 70 | #. Sessions menu 71 | #: src/termit.c:202 src/callbacks.c:418 72 | msgid "Open session" 73 | msgstr "Sitzung öffnen" 74 | 75 | #: src/termit.c:188 src/termit.c:227 76 | msgid "Paste" 77 | msgstr "Einfügen" 78 | 79 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 80 | msgid "Preferences" 81 | msgstr "Einstellungen" 82 | 83 | #: src/termit.c:171 src/termit.c:228 84 | msgid "Quit" 85 | msgstr "Beenden" 86 | 87 | #: src/termit.c:203 src/callbacks.c:388 88 | msgid "Save session" 89 | msgstr "Sitzung speichern" 90 | 91 | #: src/termit.c:229 92 | msgid "Scrollbar" 93 | msgstr "Bildlaufleiste" 94 | 95 | #: src/termit.c:205 96 | msgid "Sessions" 97 | msgstr "Sitzungen" 98 | 99 | #. Edit menu 100 | #: src/termit.c:185 src/termit.c:224 101 | msgid "Set tab name..." 102 | msgstr "Tab-Namen setzen..." 103 | 104 | #: src/callbacks.c:41 105 | msgid "" 106 | "Several tabs are opened.\n" 107 | "Close anyway?" 108 | msgstr "" 109 | "Mehrere Tabs sind geöffnet.\n" 110 | "Trotzdem schließen?" 111 | 112 | #: src/callbacks.c:297 src/callbacks.c:308 113 | msgid "Tab name" 114 | msgstr "Tab-Name" 115 | 116 | #: src/termit_preferences.c:187 117 | msgid "Title" 118 | msgstr "Titel" 119 | 120 | #: src/sessions.c:90 121 | #, c-format 122 | msgid "Unable to create directory '%s': %s" 123 | msgstr "Konnte Verzeichnis '%s' nicht erstellen: %s" 124 | 125 | #~ msgid "Background image" 126 | #~ msgstr "Hintergrundbild" 127 | 128 | #~ msgid "Image" 129 | #~ msgstr "Bild" 130 | 131 | #~ msgid "Transparency" 132 | #~ msgstr "Transparenz" 133 | 134 | #~ msgid "Visible bell" 135 | #~ msgstr "Sichtbare Glocke" 136 | 137 | #~ msgid "images" 138 | #~ msgstr "Bilder" 139 | -------------------------------------------------------------------------------- /po/es.po: -------------------------------------------------------------------------------- 1 | # Termit translation file. 2 | # Copyright (C) 2007 3 | # This file is distributed under the same license as the termit package. 4 | # Evgeny Ratnikov ratnikov.ev@gmail.com 2007. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: \n" 9 | "POT-Creation-Date: \n" 10 | "PO-Revision-Date: 2022-09-08 22:22+0100\n" 11 | "Last-Translator: SwissalpS \n" 12 | "Language-Team: \n" 13 | "Language: \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=utf-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | 18 | #: src/termit_preferences.c:219 19 | msgid "Apply to all tabs" 20 | msgstr "Aplicar a todas las pestañas" 21 | 22 | #: src/termit_preferences.c:213 23 | #, fuzzy 24 | msgid "Audible bell" 25 | msgstr "Timbre audible" 26 | 27 | #: src/termit_preferences.c:207 28 | msgid "Background" 29 | msgstr "Fondo" 30 | 31 | #: src/termit_core_api.c:464 32 | msgid "Cannot create a new tab" 33 | msgstr "No se puede crear una nueva pestaña" 34 | 35 | #: src/termit_core_api.c:416 36 | msgid "Cannot parse command. Creating tab with shell" 37 | msgstr "El comando no se entiende. Creando una nueva pestaña con shell" 38 | 39 | #: src/termit.c:170 src/termit.c:223 40 | msgid "Close tab" 41 | msgstr "Cerrar pestaña" 42 | 43 | #: src/termit.c:187 src/termit.c:226 44 | msgid "Copy" 45 | msgstr "Copiar" 46 | 47 | #: src/termit.c:190 48 | msgid "Edit" 49 | msgstr "Editar" 50 | 51 | #: src/termit.c:173 52 | msgid "File" 53 | msgstr "Archivo" 54 | 55 | #: src/termit_preferences.c:193 56 | msgid "Font" 57 | msgstr "Tipografía" 58 | 59 | #: src/termit_preferences.c:200 60 | msgid "Foreground" 61 | msgstr "Frente" 62 | 63 | #. File menu 64 | #: src/termit.c:169 src/termit.c:222 65 | msgid "New tab" 66 | msgstr "Nueva pestaña" 67 | 68 | #. Sessions menu 69 | #: src/termit.c:202 src/callbacks.c:418 70 | msgid "Open session" 71 | msgstr "Abrir sesión" 72 | 73 | #: src/termit.c:188 src/termit.c:227 74 | msgid "Paste" 75 | msgstr "Pegar" 76 | 77 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 78 | msgid "Preferences" 79 | msgstr "Preferencias" 80 | 81 | #: src/termit.c:171 src/termit.c:228 82 | msgid "Quit" 83 | msgstr "Salir" 84 | 85 | #: src/termit.c:203 src/callbacks.c:388 86 | msgid "Save session" 87 | msgstr "Guardar sesión" 88 | 89 | #: src/termit.c:229 90 | msgid "Scrollbar" 91 | msgstr "Barra de desplazamiento" 92 | 93 | #: src/termit.c:205 94 | msgid "Sessions" 95 | msgstr "Sesiones" 96 | 97 | #. Edit menu 98 | #: src/termit.c:185 src/termit.c:224 99 | msgid "Set tab name..." 100 | msgstr "Establece el nombre de la pestaña" 101 | 102 | #: src/callbacks.c:41 103 | msgid "" 104 | "Several tabs are opened.\n" 105 | "Close anyway?" 106 | msgstr "" 107 | "Hay varias pestañas abiertas.\n" 108 | "¿Cerrarlas todas igual?" 109 | 110 | #: src/callbacks.c:297 src/callbacks.c:308 111 | msgid "Tab name" 112 | msgstr "Nombre de la pestaña" 113 | 114 | #: src/termit_preferences.c:187 115 | msgid "Title" 116 | msgstr "Título" 117 | 118 | #: src/sessions.c:90 119 | #, c-format 120 | msgid "Unable to create directory '%s': %s" 121 | msgstr "No se puede crear el directorio '%s': %s." 122 | 123 | #~ msgid "Background image" 124 | #~ msgstr "Imagen de fondo" 125 | 126 | #~ msgid "Image" 127 | #~ msgstr "Imagen" 128 | 129 | #~ msgid "Transparency" 130 | #~ msgstr "Transparencia" 131 | 132 | #~ msgid "Visible bell" 133 | #~ msgstr "Timbre visible" 134 | 135 | #~ msgid "images" 136 | #~ msgstr "imágenes" 137 | -------------------------------------------------------------------------------- /po/fr.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: Termit 1.1.1\n" 4 | "POT-Creation-Date: \n" 5 | "PO-Revision-Date: 2022-09-08 22:22+0100\n" 6 | "Last-Translator: SwissalpS \n" 7 | "Language-Team: Mallory Mollo \n" 8 | "Language: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=utf-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: French\n" 13 | "X-Poedit-Country: FRANCE\n" 14 | 15 | #: src/termit_preferences.c:219 16 | msgid "Apply to all tabs" 17 | msgstr "Appliquer à tous les onglets" 18 | 19 | #: src/termit_preferences.c:213 20 | msgid "Audible bell" 21 | msgstr "Cloche sonore" 22 | 23 | #: src/termit_preferences.c:207 24 | msgid "Background" 25 | msgstr "Fond" 26 | 27 | #: src/termit_core_api.c:464 28 | msgid "Cannot create a new tab" 29 | msgstr "Impossible de créer un nouvel onglet" 30 | 31 | #: src/termit_core_api.c:416 32 | msgid "Cannot parse command. Creating tab with shell" 33 | msgstr "Impossible d'analyser la commande. Création d'onglet avec shell" 34 | 35 | #: src/termit.c:170 src/termit.c:223 36 | msgid "Close tab" 37 | msgstr "Fermer l'onglet" 38 | 39 | #: src/termit.c:187 src/termit.c:226 40 | msgid "Copy" 41 | msgstr "Copie" 42 | 43 | #: src/termit.c:190 44 | msgid "Edit" 45 | msgstr "Éditer" 46 | 47 | #: src/termit.c:173 48 | msgid "File" 49 | msgstr "Fichier" 50 | 51 | #: src/termit_preferences.c:193 52 | msgid "Font" 53 | msgstr "Fonte" 54 | 55 | #: src/termit_preferences.c:200 56 | msgid "Foreground" 57 | msgstr "Premier plan" 58 | 59 | #. File menu 60 | #: src/termit.c:169 src/termit.c:222 61 | msgid "New tab" 62 | msgstr "Nouvel onglet" 63 | 64 | #. Sessions menu 65 | #: src/termit.c:202 src/callbacks.c:418 66 | msgid "Open session" 67 | msgstr "Ouvrir une session" 68 | 69 | #: src/termit.c:188 src/termit.c:227 70 | msgid "Paste" 71 | msgstr "Coller" 72 | 73 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 74 | msgid "Preferences" 75 | msgstr "Préférences" 76 | 77 | #: src/termit.c:171 src/termit.c:228 78 | msgid "Quit" 79 | msgstr "Quitter" 80 | 81 | #: src/termit.c:203 src/callbacks.c:388 82 | msgid "Save session" 83 | msgstr "Enregistrer la session" 84 | 85 | #: src/termit.c:229 86 | msgid "Scrollbar" 87 | msgstr "Barre de défilement" 88 | 89 | #: src/termit.c:205 90 | msgid "Sessions" 91 | msgstr "Sessions" 92 | 93 | #. Edit menu 94 | #: src/termit.c:185 src/termit.c:224 95 | msgid "Set tab name..." 96 | msgstr "Définir le nom de l'onglet..." 97 | 98 | #: src/callbacks.c:41 99 | msgid "" 100 | "Several tabs are opened.\n" 101 | "Close anyway?" 102 | msgstr "" 103 | "Vous êtes sur le point de fermer plusieurs onglets.\n" 104 | "Voulez-vous vraiment continuer ?" 105 | 106 | #: src/callbacks.c:297 src/callbacks.c:308 107 | msgid "Tab name" 108 | msgstr "Nom de l'onglet" 109 | 110 | #: src/termit_preferences.c:187 111 | #, fuzzy 112 | msgid "Title" 113 | msgstr "Fichier" 114 | 115 | #: src/sessions.c:90 116 | #, c-format 117 | msgid "Unable to create directory '%s': %s" 118 | msgstr "Impossible de créer le dossier '%s': %s" 119 | 120 | #~ msgid "Bookmarks" 121 | #~ msgstr "Marques-page" 122 | 123 | #~ msgid "Encoding" 124 | #~ msgstr "Encodage" 125 | 126 | #~ msgid "Select font" 127 | #~ msgstr "Définir la police" 128 | -------------------------------------------------------------------------------- /po/hu.po: -------------------------------------------------------------------------------- 1 | # Termit translation file. 2 | # Copyright (C) 2007 3 | # This file is distributed under the same license as the termit package. 4 | # Evgeny Ratnikov ratnikov.ev@gmail.com 2007. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: 1.0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: \n" 11 | "PO-Revision-Date: 2011-12-19 21:23+0100\n" 12 | "Last-Translator: Peter Polonkai \n" 13 | "Language-Team: hu\n" 14 | "Language: \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #: src/termit_preferences.c:219 20 | msgid "Apply to all tabs" 21 | msgstr "" 22 | 23 | #: src/termit_preferences.c:213 24 | #, fuzzy 25 | msgid "Audible bell" 26 | msgstr "Hallható figyelmeztetés" 27 | 28 | #: src/termit_preferences.c:207 29 | msgid "Background" 30 | msgstr "Háttér" 31 | 32 | #: src/termit_core_api.c:464 33 | msgid "Cannot create a new tab" 34 | msgstr "Nem sikerült új fület létrehozni" 35 | 36 | #: src/termit_core_api.c:416 37 | msgid "Cannot parse command. Creating tab with shell" 38 | msgstr "" 39 | "Nem lehetséges a parancs értelmezése. Fül létrehozása shell segítségével" 40 | 41 | #: src/termit.c:170 src/termit.c:223 42 | msgid "Close tab" 43 | msgstr "" 44 | 45 | #: src/termit.c:187 src/termit.c:226 46 | msgid "Copy" 47 | msgstr "" 48 | 49 | #: src/termit.c:190 50 | msgid "Edit" 51 | msgstr "Szerkesztés" 52 | 53 | #: src/termit.c:173 54 | msgid "File" 55 | msgstr "Fájl" 56 | 57 | #: src/termit_preferences.c:193 58 | msgid "Font" 59 | msgstr "Betűtípus" 60 | 61 | #: src/termit_preferences.c:200 62 | msgid "Foreground" 63 | msgstr "Előtér" 64 | 65 | #. File menu 66 | #: src/termit.c:169 src/termit.c:222 67 | msgid "New tab" 68 | msgstr "" 69 | 70 | #. Sessions menu 71 | #: src/termit.c:202 src/callbacks.c:418 72 | msgid "Open session" 73 | msgstr "Megnyitás" 74 | 75 | #: src/termit.c:188 src/termit.c:227 76 | msgid "Paste" 77 | msgstr "" 78 | 79 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 80 | msgid "Preferences" 81 | msgstr "" 82 | 83 | #: src/termit.c:171 src/termit.c:228 84 | msgid "Quit" 85 | msgstr "" 86 | 87 | #: src/termit.c:203 src/callbacks.c:388 88 | msgid "Save session" 89 | msgstr "Mentés" 90 | 91 | #: src/termit.c:229 92 | msgid "Scrollbar" 93 | msgstr "Gördítősáv" 94 | 95 | #: src/termit.c:205 96 | msgid "Sessions" 97 | msgstr "Munkamenetek" 98 | 99 | #. Edit menu 100 | #: src/termit.c:185 src/termit.c:224 101 | msgid "Set tab name..." 102 | msgstr "Fül átnevezése..." 103 | 104 | #: src/callbacks.c:41 105 | msgid "" 106 | "Several tabs are opened.\n" 107 | "Close anyway?" 108 | msgstr "" 109 | "Több fül is nyitva van.\n" 110 | "Bezárja mind?" 111 | 112 | #: src/callbacks.c:297 src/callbacks.c:308 113 | msgid "Tab name" 114 | msgstr "Fül neve" 115 | 116 | #: src/termit_preferences.c:187 117 | msgid "Title" 118 | msgstr "Cím" 119 | 120 | #: src/sessions.c:90 121 | #, c-format 122 | msgid "Unable to create directory '%s': %s" 123 | msgstr "A könyvtár létrehozása sikertelen '%s': %s" 124 | 125 | #~ msgid "Background image" 126 | #~ msgstr "Háttérkép" 127 | 128 | #~ msgid "Image" 129 | #~ msgstr "Kép" 130 | 131 | #~ msgid "Transparency" 132 | #~ msgstr "Átlátszóság" 133 | 134 | #~ msgid "Visible bell" 135 | #~ msgstr "Látható figyelmeztetés" 136 | 137 | #~ msgid "images" 138 | #~ msgstr "képek" 139 | -------------------------------------------------------------------------------- /po/ja.po: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2011 Nobuhiro Iwamatsu 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: termit japanese translate\n" 5 | "POT-Creation-Date: \n" 6 | "PO-Revision-Date: 2011-09-01 02:28+0900\n" 7 | "Last-Translator: Nobuhiro Iwamatsu \n" 8 | "Language-Team: \n" 9 | "Language: \n" 10 | "MIME-Version: 1.0\n" 11 | "Content-Type: text/plain; charset=utf-8\n" 12 | "Content-Transfer-Encoding: 8bit\n" 13 | "X-Poedit-Language: Japanese\n" 14 | "X-Poedit-Country: JAPAN\n" 15 | 16 | #: src/termit_preferences.c:219 17 | msgid "Apply to all tabs" 18 | msgstr "" 19 | 20 | #: src/termit_preferences.c:213 21 | #, fuzzy 22 | msgid "Audible bell" 23 | msgstr "可聴ベル" 24 | 25 | #: src/termit_preferences.c:207 26 | msgid "Background" 27 | msgstr "背景" 28 | 29 | #: src/termit_core_api.c:464 30 | msgid "Cannot create a new tab" 31 | msgstr "新しいタブを作成できません" 32 | 33 | #: src/termit_core_api.c:416 34 | msgid "Cannot parse command. Creating tab with shell" 35 | msgstr "コマンドを解析できません。シェル経由でタブを作成します" 36 | 37 | #: src/termit.c:170 src/termit.c:223 38 | msgid "Close tab" 39 | msgstr "" 40 | 41 | #: src/termit.c:187 src/termit.c:226 42 | msgid "Copy" 43 | msgstr "" 44 | 45 | #: src/termit.c:190 46 | msgid "Edit" 47 | msgstr "編集" 48 | 49 | #: src/termit.c:173 50 | msgid "File" 51 | msgstr "ファイル" 52 | 53 | #: src/termit_preferences.c:193 54 | msgid "Font" 55 | msgstr "フォント" 56 | 57 | #: src/termit_preferences.c:200 58 | msgid "Foreground" 59 | msgstr "前景" 60 | 61 | #. File menu 62 | #: src/termit.c:169 src/termit.c:222 63 | msgid "New tab" 64 | msgstr "" 65 | 66 | #. Sessions menu 67 | #: src/termit.c:202 src/callbacks.c:418 68 | msgid "Open session" 69 | msgstr "セッションを開く" 70 | 71 | #: src/termit.c:188 src/termit.c:227 72 | msgid "Paste" 73 | msgstr "" 74 | 75 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 76 | msgid "Preferences" 77 | msgstr "" 78 | 79 | #: src/termit.c:171 src/termit.c:228 80 | msgid "Quit" 81 | msgstr "" 82 | 83 | #: src/termit.c:203 src/callbacks.c:388 84 | msgid "Save session" 85 | msgstr "セッションを保存する" 86 | 87 | #: src/termit.c:229 88 | msgid "Scrollbar" 89 | msgstr "スクロールバー" 90 | 91 | #: src/termit.c:205 92 | msgid "Sessions" 93 | msgstr "セッション" 94 | 95 | #. Edit menu 96 | #: src/termit.c:185 src/termit.c:224 97 | msgid "Set tab name..." 98 | msgstr "タブ名を設定する" 99 | 100 | #: src/callbacks.c:41 101 | msgid "" 102 | "Several tabs are opened.\n" 103 | "Close anyway?" 104 | msgstr "終了しますか?" 105 | 106 | #: src/callbacks.c:297 src/callbacks.c:308 107 | msgid "Tab name" 108 | msgstr "タブ名" 109 | 110 | #: src/termit_preferences.c:187 111 | msgid "Title" 112 | msgstr "タイトル" 113 | 114 | #: src/sessions.c:90 115 | #, c-format 116 | msgid "Unable to create directory '%s': %s" 117 | msgstr "ディレクトリ '%s' が生成できません: %s" 118 | 119 | #~ msgid "Background image" 120 | #~ msgstr "背景画像" 121 | 122 | #~ msgid "Image" 123 | #~ msgstr "画像" 124 | 125 | #~ msgid "Transparency" 126 | #~ msgstr "透過" 127 | 128 | #~ msgid "Visible bell" 129 | #~ msgstr "可視ベル" 130 | 131 | #~ msgid "images" 132 | #~ msgstr "画像" 133 | -------------------------------------------------------------------------------- /po/ko.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: termit korean translate\n" 4 | "POT-Creation-Date: \n" 5 | "PO-Revision-Date: 2008-09-02 05:26+0900\n" 6 | "Last-Translator: SeonKon Choi \n" 7 | "Language-Team: \n" 8 | "Language: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=utf-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: Korean\n" 13 | "X-Poedit-Country: KOREA, REPUBLIC OF\n" 14 | 15 | #: src/termit_preferences.c:219 16 | msgid "Apply to all tabs" 17 | msgstr "" 18 | 19 | #: src/termit_preferences.c:213 20 | msgid "Audible bell" 21 | msgstr "" 22 | 23 | #: src/termit_preferences.c:207 24 | msgid "Background" 25 | msgstr "" 26 | 27 | #: src/termit_core_api.c:464 28 | msgid "Cannot create a new tab" 29 | msgstr "새 탭을 만들 수 없습니다" 30 | 31 | #: src/termit_core_api.c:416 32 | msgid "Cannot parse command. Creating tab with shell" 33 | msgstr "명령을 해석할 수 없습니다. 쉘을 이용한 새 탭을 만듭니다" 34 | 35 | #: src/termit.c:170 src/termit.c:223 36 | msgid "Close tab" 37 | msgstr "" 38 | 39 | #: src/termit.c:187 src/termit.c:226 40 | msgid "Copy" 41 | msgstr "" 42 | 43 | #: src/termit.c:190 44 | msgid "Edit" 45 | msgstr "편집" 46 | 47 | #: src/termit.c:173 48 | msgid "File" 49 | msgstr "파일" 50 | 51 | #: src/termit_preferences.c:193 52 | msgid "Font" 53 | msgstr "" 54 | 55 | #: src/termit_preferences.c:200 56 | msgid "Foreground" 57 | msgstr "" 58 | 59 | #. File menu 60 | #: src/termit.c:169 src/termit.c:222 61 | msgid "New tab" 62 | msgstr "" 63 | 64 | #. Sessions menu 65 | #: src/termit.c:202 src/callbacks.c:418 66 | msgid "Open session" 67 | msgstr "세션 열기" 68 | 69 | #: src/termit.c:188 src/termit.c:227 70 | msgid "Paste" 71 | msgstr "" 72 | 73 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 74 | msgid "Preferences" 75 | msgstr "" 76 | 77 | #: src/termit.c:171 src/termit.c:228 78 | msgid "Quit" 79 | msgstr "" 80 | 81 | #: src/termit.c:203 src/callbacks.c:388 82 | msgid "Save session" 83 | msgstr "세션 저장" 84 | 85 | #: src/termit.c:229 86 | msgid "Scrollbar" 87 | msgstr "스크롤 바" 88 | 89 | #: src/termit.c:205 90 | msgid "Sessions" 91 | msgstr "세션" 92 | 93 | #. Edit menu 94 | #: src/termit.c:185 src/termit.c:224 95 | msgid "Set tab name..." 96 | msgstr "탭 이름 바꾸기" 97 | 98 | #: src/callbacks.c:41 99 | msgid "" 100 | "Several tabs are opened.\n" 101 | "Close anyway?" 102 | msgstr "" 103 | "다른 탭들이 아직 열려 있습니다.\n" 104 | "전부 닫고 종료할까요 ?" 105 | 106 | #: src/callbacks.c:297 src/callbacks.c:308 107 | msgid "Tab name" 108 | msgstr "탭 이름" 109 | 110 | #: src/termit_preferences.c:187 111 | #, fuzzy 112 | msgid "Title" 113 | msgstr "파일" 114 | 115 | #: src/sessions.c:90 116 | #, c-format 117 | msgid "Unable to create directory '%s': %s" 118 | msgstr "디렉토리를 만들 수 없습니다 '%s': %s" 119 | 120 | #~ msgid "Bookmarks" 121 | #~ msgstr "책갈피" 122 | 123 | #~ msgid "Encoding" 124 | #~ msgstr "문자집합" 125 | 126 | #~ msgid "Select font" 127 | #~ msgstr "글꼴 바꾸기" 128 | -------------------------------------------------------------------------------- /po/nl.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: \n" 4 | "POT-Creation-Date: \n" 5 | "PO-Revision-Date: \n" 6 | "Last-Translator: Heimen Stoffels \n" 7 | "Language-Team: \n" 8 | "Language: nl\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 13 | "X-Generator: Poedit 3.0\n" 14 | 15 | #: src/termit_preferences.c:219 16 | msgid "Apply to all tabs" 17 | msgstr "Toepassen op alle tabbladen" 18 | 19 | #: src/termit_preferences.c:213 20 | msgid "Audible bell" 21 | msgstr "Luide bel" 22 | 23 | #: src/termit_preferences.c:207 24 | msgid "Background" 25 | msgstr "Achtergrond" 26 | 27 | #: src/termit_core_api.c:464 28 | msgid "Cannot create a new tab" 29 | msgstr "Er kan geen nieuw tabblad worden geopend" 30 | 31 | #: src/termit_core_api.c:416 32 | msgid "Cannot parse command. Creating tab with shell" 33 | msgstr "" 34 | "De opdracht kan niet worden verwerkt. Bezig met openen van tabblad met shell…" 35 | 36 | #: src/termit.c:170 src/termit.c:223 37 | msgid "Close tab" 38 | msgstr "Verwijderen" 39 | 40 | #: src/termit.c:187 src/termit.c:226 41 | msgid "Copy" 42 | msgstr "Kopiëren" 43 | 44 | #: src/termit.c:190 45 | msgid "Edit" 46 | msgstr "Bewerken" 47 | 48 | #: src/termit.c:173 49 | msgid "File" 50 | msgstr "Bestand" 51 | 52 | #: src/termit_preferences.c:193 53 | msgid "Font" 54 | msgstr "Lettertype" 55 | 56 | #: src/termit_preferences.c:200 57 | msgid "Foreground" 58 | msgstr "Voorgrond" 59 | 60 | #. File menu 61 | #: src/termit.c:169 src/termit.c:222 62 | msgid "New tab" 63 | msgstr "Openen" 64 | 65 | #. Sessions menu 66 | #: src/termit.c:202 src/callbacks.c:418 67 | msgid "Open session" 68 | msgstr "Sessie openen" 69 | 70 | #: src/termit.c:188 src/termit.c:227 71 | msgid "Paste" 72 | msgstr "Plakken" 73 | 74 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 75 | msgid "Preferences" 76 | msgstr "Instellingen" 77 | 78 | #: src/termit.c:171 src/termit.c:228 79 | msgid "Quit" 80 | msgstr "Afsluiten" 81 | 82 | #: src/termit.c:203 src/callbacks.c:388 83 | msgid "Save session" 84 | msgstr "Sessie opslaan" 85 | 86 | #: src/termit.c:229 87 | msgid "Scrollbar" 88 | msgstr "Schuifbalk" 89 | 90 | #: src/termit.c:205 91 | msgid "Sessions" 92 | msgstr "Sessies" 93 | 94 | #. Edit menu 95 | #: src/termit.c:185 src/termit.c:224 96 | msgid "Set tab name..." 97 | msgstr "Tabbladnaam instellen…" 98 | 99 | #: src/callbacks.c:41 100 | msgid "" 101 | "Several tabs are opened.\n" 102 | "Close anyway?" 103 | msgstr "" 104 | "Er zijn nog openstaande tabbladen.\n" 105 | "Weet u zeker dat u wilt doorgaan?" 106 | 107 | #: src/callbacks.c:297 src/callbacks.c:308 108 | msgid "Tab name" 109 | msgstr "Tabbladnaam" 110 | 111 | #: src/termit_preferences.c:187 112 | msgid "Title" 113 | msgstr "Naam" 114 | 115 | #: src/sessions.c:90 116 | #, c-format 117 | msgid "Unable to create directory '%s': %s" 118 | msgstr "De map ‘%s’ kan niet worden aangemaakt: %s" 119 | -------------------------------------------------------------------------------- /po/pl.po: -------------------------------------------------------------------------------- 1 | # Polish translation of termit. 2 | # Copyright (C) 2007 3 | # This file is distributed under the same license as the termit package. 4 | # Miś Uszatek , 2012 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: termit-2.9.3\n" 9 | "POT-Creation-Date: \n" 10 | "PO-Revision-Date: 2012-05-02 20:02+0100\n" 11 | "Last-Translator: Miś Uszatek \n" 12 | "Language-Team: Polish\n" 13 | "Language: pl\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " 18 | "|| n%100>=20) ? 1 : 2);\n" 19 | 20 | #: src/termit_preferences.c:219 21 | msgid "Apply to all tabs" 22 | msgstr "" 23 | 24 | #: src/termit_preferences.c:213 25 | #, fuzzy 26 | msgid "Audible bell" 27 | msgstr "Głośny dzwonek" 28 | 29 | #: src/termit_preferences.c:207 30 | msgid "Background" 31 | msgstr "Tło" 32 | 33 | #: src/termit_core_api.c:464 34 | msgid "Cannot create a new tab" 35 | msgstr "Nie można utworzyć nowej karty" 36 | 37 | #: src/termit_core_api.c:416 38 | msgid "Cannot parse command. Creating tab with shell" 39 | msgstr "Nie można przetworzyć polecenia. Tworzenia karty z powłoki" 40 | 41 | #: src/termit.c:170 src/termit.c:223 42 | msgid "Close tab" 43 | msgstr "" 44 | 45 | #: src/termit.c:187 src/termit.c:226 46 | msgid "Copy" 47 | msgstr "" 48 | 49 | #: src/termit.c:190 50 | msgid "Edit" 51 | msgstr "Edycja" 52 | 53 | #: src/termit.c:173 54 | msgid "File" 55 | msgstr "Plik" 56 | 57 | #: src/termit_preferences.c:193 58 | msgid "Font" 59 | msgstr "Czcionka" 60 | 61 | #: src/termit_preferences.c:200 62 | msgid "Foreground" 63 | msgstr "Pierwszy plan" 64 | 65 | #. File menu 66 | #: src/termit.c:169 src/termit.c:222 67 | msgid "New tab" 68 | msgstr "" 69 | 70 | #. Sessions menu 71 | #: src/termit.c:202 src/callbacks.c:418 72 | msgid "Open session" 73 | msgstr "Otwórz sesje" 74 | 75 | #: src/termit.c:188 src/termit.c:227 76 | msgid "Paste" 77 | msgstr "" 78 | 79 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 80 | msgid "Preferences" 81 | msgstr "" 82 | 83 | #: src/termit.c:171 src/termit.c:228 84 | msgid "Quit" 85 | msgstr "" 86 | 87 | #: src/termit.c:203 src/callbacks.c:388 88 | msgid "Save session" 89 | msgstr "Zapisz sesje " 90 | 91 | #: src/termit.c:229 92 | msgid "Scrollbar" 93 | msgstr "Pasek przewijania" 94 | 95 | #: src/termit.c:205 96 | msgid "Sessions" 97 | msgstr "Sesja" 98 | 99 | #. Edit menu 100 | #: src/termit.c:185 src/termit.c:224 101 | msgid "Set tab name..." 102 | msgstr "Ustaw nazwe karty..." 103 | 104 | #: src/callbacks.c:41 105 | msgid "" 106 | "Several tabs are opened.\n" 107 | "Close anyway?" 108 | msgstr "" 109 | "Kilka kart jest otwartych.\n" 110 | "Zamknąć pomimo to?" 111 | 112 | #: src/callbacks.c:297 src/callbacks.c:308 113 | msgid "Tab name" 114 | msgstr "Nazwa Karty" 115 | 116 | #: src/termit_preferences.c:187 117 | msgid "Title" 118 | msgstr "Tytuł" 119 | 120 | #: src/sessions.c:90 121 | #, c-format 122 | msgid "Unable to create directory '%s': %s" 123 | msgstr "Nie można utworzyć katalogu '%s': %s" 124 | 125 | #~ msgid "Background image" 126 | #~ msgstr "Obraz tła" 127 | 128 | #~ msgid "Image" 129 | #~ msgstr "Obraz" 130 | 131 | #~ msgid "Transparency" 132 | #~ msgstr "Przezroczystość" 133 | 134 | #~ msgid "Visible bell" 135 | #~ msgstr "Widoczny dzwonek" 136 | 137 | #~ msgid "images" 138 | #~ msgstr "obrazy" 139 | -------------------------------------------------------------------------------- /po/ru.po: -------------------------------------------------------------------------------- 1 | # Termit translation file. 2 | # Copyright (C) 2007 3 | # This file is distributed under the same license as the termit package. 4 | # Evgeny Ratnikov ratnikov.ev@gmail.com 2007. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: 1.0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2007-09-25 09:19+0400\n" 11 | "PO-Revision-Date: 2007-12-15 18:05+0400\n" 12 | "Last-Translator: Evgeny V. Ratnikov ratnikov.ev@gmail.com\n" 13 | "Language-Team: ru_RU\n" 14 | "Language: \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #: src/termit_preferences.c:219 20 | msgid "Apply to all tabs" 21 | msgstr "" 22 | 23 | #: src/termit_preferences.c:213 24 | msgid "Audible bell" 25 | msgstr "" 26 | 27 | #: src/termit_preferences.c:207 28 | msgid "Background" 29 | msgstr "" 30 | 31 | #: src/termit_core_api.c:464 32 | msgid "Cannot create a new tab" 33 | msgstr "Ошибка открытия новой вкладки" 34 | 35 | #: src/termit_core_api.c:416 36 | msgid "Cannot parse command. Creating tab with shell" 37 | msgstr "" 38 | 39 | #: src/termit.c:170 src/termit.c:223 40 | msgid "Close tab" 41 | msgstr "" 42 | 43 | #: src/termit.c:187 src/termit.c:226 44 | msgid "Copy" 45 | msgstr "" 46 | 47 | #: src/termit.c:190 48 | msgid "Edit" 49 | msgstr "Правка" 50 | 51 | #: src/termit.c:173 52 | msgid "File" 53 | msgstr "Файл" 54 | 55 | #: src/termit_preferences.c:193 56 | msgid "Font" 57 | msgstr "" 58 | 59 | #: src/termit_preferences.c:200 60 | msgid "Foreground" 61 | msgstr "" 62 | 63 | #. File menu 64 | #: src/termit.c:169 src/termit.c:222 65 | msgid "New tab" 66 | msgstr "" 67 | 68 | #. Sessions menu 69 | #: src/termit.c:202 src/callbacks.c:418 70 | msgid "Open session" 71 | msgstr "Открыть сессию" 72 | 73 | #: src/termit.c:188 src/termit.c:227 74 | msgid "Paste" 75 | msgstr "" 76 | 77 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 78 | msgid "Preferences" 79 | msgstr "" 80 | 81 | #: src/termit.c:171 src/termit.c:228 82 | msgid "Quit" 83 | msgstr "" 84 | 85 | #: src/termit.c:203 src/callbacks.c:388 86 | msgid "Save session" 87 | msgstr "Сохранить сессию" 88 | 89 | #: src/termit.c:229 90 | msgid "Scrollbar" 91 | msgstr "Полоса прокрутки" 92 | 93 | #: src/termit.c:205 94 | msgid "Sessions" 95 | msgstr "Сессии" 96 | 97 | #. Edit menu 98 | #: src/termit.c:185 src/termit.c:224 99 | msgid "Set tab name..." 100 | msgstr "Заголовок вкладки" 101 | 102 | #: src/callbacks.c:41 103 | msgid "" 104 | "Several tabs are opened.\n" 105 | "Close anyway?" 106 | msgstr "" 107 | "Открыто несколько вкладок.\n" 108 | "Закрыть?" 109 | 110 | #: src/callbacks.c:297 src/callbacks.c:308 111 | msgid "Tab name" 112 | msgstr "Заголовок вкладки" 113 | 114 | #: src/termit_preferences.c:187 115 | #, fuzzy 116 | msgid "Title" 117 | msgstr "Файл" 118 | 119 | #: src/sessions.c:90 120 | #, c-format 121 | msgid "Unable to create directory '%s': %s" 122 | msgstr "Невозможно создать директорию '%s': %s" 123 | 124 | #~ msgid "Bookmarks" 125 | #~ msgstr "Закладки" 126 | 127 | #~ msgid "Encoding" 128 | #~ msgstr "Кодировка" 129 | 130 | #~ msgid "Select font" 131 | #~ msgstr "Выбор шрифта" 132 | -------------------------------------------------------------------------------- /po/sv.po: -------------------------------------------------------------------------------- 1 | #: src/termit_preferences.c:219 2 | msgid "Apply to all tabs" 3 | msgstr "" 4 | 5 | #: src/termit_preferences.c:213 6 | #, fuzzy 7 | msgid "Audible bell" 8 | msgstr "Ljudsignal" 9 | 10 | #: src/termit_preferences.c:207 11 | msgid "Background" 12 | msgstr "Bakgrund" 13 | 14 | #: src/termit_core_api.c:464 15 | msgid "Cannot create a new tab" 16 | msgstr "Kan inte skapa ny flik" 17 | 18 | #: src/termit_core_api.c:416 19 | msgid "Cannot parse command. Creating tab with shell" 20 | msgstr "Kan inte tolka kommando. Skapar interaktiv flik." 21 | 22 | #: src/termit.c:170 src/termit.c:223 23 | msgid "Close tab" 24 | msgstr "" 25 | 26 | #: src/termit.c:187 src/termit.c:226 27 | msgid "Copy" 28 | msgstr "" 29 | 30 | #: src/termit.c:190 31 | msgid "Edit" 32 | msgstr "Redigera" 33 | 34 | #: src/termit.c:173 35 | msgid "File" 36 | msgstr "Arkiv" 37 | 38 | #: src/termit_preferences.c:193 39 | msgid "Font" 40 | msgstr "Teckensnitt" 41 | 42 | #: src/termit_preferences.c:200 43 | msgid "Foreground" 44 | msgstr "Frgrund" 45 | 46 | #. File menu 47 | #: src/termit.c:169 src/termit.c:222 48 | msgid "New tab" 49 | msgstr "" 50 | 51 | #. Sessions menu 52 | #: src/termit.c:202 src/callbacks.c:418 53 | msgid "Open session" 54 | msgstr "ppna arbetspass" 55 | 56 | #: src/termit.c:188 src/termit.c:227 57 | msgid "Paste" 58 | msgstr "" 59 | 60 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 61 | msgid "Preferences" 62 | msgstr "" 63 | 64 | #: src/termit.c:171 src/termit.c:228 65 | msgid "Quit" 66 | msgstr "" 67 | 68 | #: src/termit.c:203 src/callbacks.c:388 69 | msgid "Save session" 70 | msgstr "Spara arbetspass" 71 | 72 | #: src/termit.c:229 73 | msgid "Scrollbar" 74 | msgstr "Rullningslist" 75 | 76 | #: src/termit.c:205 77 | msgid "Sessions" 78 | msgstr "Arbetspass" 79 | 80 | #. Edit menu 81 | #: src/termit.c:185 src/termit.c:224 82 | msgid "Set tab name..." 83 | msgstr "Namnge fliken..." 84 | 85 | #: src/callbacks.c:41 86 | msgid "" 87 | "Several tabs are opened.\n" 88 | "Close anyway?" 89 | msgstr "" 90 | 91 | #: src/callbacks.c:297 src/callbacks.c:308 92 | msgid "Tab name" 93 | msgstr "Fliknamn" 94 | 95 | #: src/termit_preferences.c:187 96 | msgid "Title" 97 | msgstr "Rubrik" 98 | 99 | #: src/sessions.c:90 100 | #, c-format 101 | msgid "Unable to create directory '%s': %s" 102 | msgstr "Kan inte skapa mappen '%s': %s" 103 | 104 | #~ msgid "Background image" 105 | #~ msgstr "Bakgrundsbild" 106 | 107 | #~ msgid "Image" 108 | #~ msgstr "Avbild" 109 | 110 | #~ msgid "Transparency" 111 | #~ msgstr "Genomskinlighet" 112 | 113 | #~ msgid "Visible bell" 114 | #~ msgstr "Ljudsignal" 115 | 116 | #~ msgid "images" 117 | #~ msgstr "avbilder" 118 | -------------------------------------------------------------------------------- /po/termit.pot: -------------------------------------------------------------------------------- 1 | #: src/termit_preferences.c:219 2 | msgid "Apply to all tabs" 3 | msgstr "" 4 | 5 | #: src/termit_preferences.c:213 6 | msgid "Audible bell" 7 | msgstr "" 8 | 9 | #: src/termit_preferences.c:207 10 | msgid "Background" 11 | msgstr "" 12 | 13 | #: src/termit_core_api.c:464 14 | msgid "Cannot create a new tab" 15 | msgstr "" 16 | 17 | #: src/termit_core_api.c:416 18 | msgid "Cannot parse command. Creating tab with shell" 19 | msgstr "" 20 | 21 | #: src/termit.c:170 src/termit.c:223 22 | msgid "Close tab" 23 | msgstr "" 24 | 25 | #: src/termit.c:187 src/termit.c:226 26 | msgid "Copy" 27 | msgstr "" 28 | 29 | #: src/termit.c:190 30 | msgid "Edit" 31 | msgstr "" 32 | 33 | #: src/termit.c:173 34 | msgid "File" 35 | msgstr "" 36 | 37 | #: src/termit_preferences.c:193 38 | msgid "Font" 39 | msgstr "" 40 | 41 | #: src/termit_preferences.c:200 42 | msgid "Foreground" 43 | msgstr "" 44 | 45 | #. File menu 46 | #: src/termit.c:169 src/termit.c:222 47 | msgid "New tab" 48 | msgstr "" 49 | 50 | #. Sessions menu 51 | #: src/termit.c:202 src/callbacks.c:418 52 | msgid "Open session" 53 | msgstr "" 54 | 55 | #: src/termit.c:188 src/termit.c:227 56 | msgid "Paste" 57 | msgstr "" 58 | 59 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 60 | msgid "Preferences" 61 | msgstr "" 62 | 63 | #: src/termit.c:171 src/termit.c:228 64 | msgid "Quit" 65 | msgstr "" 66 | 67 | #: src/termit.c:203 src/callbacks.c:388 68 | msgid "Save session" 69 | msgstr "" 70 | 71 | #: src/termit.c:229 72 | msgid "Scrollbar" 73 | msgstr "" 74 | 75 | #: src/termit.c:205 76 | msgid "Sessions" 77 | msgstr "" 78 | 79 | #. Edit menu 80 | #: src/termit.c:185 src/termit.c:224 81 | msgid "Set tab name..." 82 | msgstr "" 83 | 84 | #: src/callbacks.c:41 85 | msgid "" 86 | "Several tabs are opened.\n" 87 | "Close anyway?" 88 | msgstr "" 89 | 90 | #: src/callbacks.c:297 src/callbacks.c:308 91 | msgid "Tab name" 92 | msgstr "" 93 | 94 | #: src/termit_preferences.c:187 95 | msgid "Title" 96 | msgstr "" 97 | 98 | #: src/sessions.c:90 99 | #, c-format 100 | msgid "Unable to create directory '%s': %s" 101 | msgstr "" 102 | -------------------------------------------------------------------------------- /po/zh_TW.po: -------------------------------------------------------------------------------- 1 | # Traditional Chinese messages for termit. 2 | # Copyright (C) 2008 Tetralet . 3 | # This file is distributed under the same license as termit. 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: termit\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "POT-Creation-Date: 2008-02-05 22:50+0000\n" 10 | "PO-Revision-Date: 2008-02-20 11:18+0800\n" 11 | "Last-Translator: Tetralet \n" 12 | "MIME-Version: 1.0\n" 13 | "Content-Type: text/plain; charset=UTF-8\n" 14 | "Content-Transfer-Encoding: 8bit\n" 15 | 16 | #: src/termit_preferences.c:219 17 | msgid "Apply to all tabs" 18 | msgstr "" 19 | 20 | #: src/termit_preferences.c:213 21 | msgid "Audible bell" 22 | msgstr "" 23 | 24 | #: src/termit_preferences.c:207 25 | msgid "Background" 26 | msgstr "" 27 | 28 | #: src/termit_core_api.c:464 29 | msgid "Cannot create a new tab" 30 | msgstr "無法建立新分頁" 31 | 32 | #: src/termit_core_api.c:416 33 | msgid "Cannot parse command. Creating tab with shell" 34 | msgstr "" 35 | 36 | #: src/termit.c:170 src/termit.c:223 37 | msgid "Close tab" 38 | msgstr "" 39 | 40 | #: src/termit.c:187 src/termit.c:226 41 | msgid "Copy" 42 | msgstr "" 43 | 44 | #: src/termit.c:190 45 | msgid "Edit" 46 | msgstr "編輯" 47 | 48 | #: src/termit.c:173 49 | msgid "File" 50 | msgstr "檔案" 51 | 52 | #: src/termit_preferences.c:193 53 | msgid "Font" 54 | msgstr "" 55 | 56 | #: src/termit_preferences.c:200 57 | msgid "Foreground" 58 | msgstr "" 59 | 60 | #. File menu 61 | #: src/termit.c:169 src/termit.c:222 62 | msgid "New tab" 63 | msgstr "" 64 | 65 | #. Sessions menu 66 | #: src/termit.c:202 src/callbacks.c:418 67 | msgid "Open session" 68 | msgstr "開啟作業階段" 69 | 70 | #: src/termit.c:188 src/termit.c:227 71 | msgid "Paste" 72 | msgstr "" 73 | 74 | #: src/termit.c:186 src/termit.c:225 src/termit_preferences.c:167 75 | msgid "Preferences" 76 | msgstr "" 77 | 78 | #: src/termit.c:171 src/termit.c:228 79 | msgid "Quit" 80 | msgstr "" 81 | 82 | #: src/termit.c:203 src/callbacks.c:388 83 | msgid "Save session" 84 | msgstr "儲存作業階段" 85 | 86 | #: src/termit.c:229 87 | msgid "Scrollbar" 88 | msgstr "" 89 | 90 | #: src/termit.c:205 91 | msgid "Sessions" 92 | msgstr "作業階段" 93 | 94 | #. Edit menu 95 | #: src/termit.c:185 src/termit.c:224 96 | msgid "Set tab name..." 97 | msgstr "設定分頁名稱..." 98 | 99 | #: src/callbacks.c:41 100 | msgid "" 101 | "Several tabs are opened.\n" 102 | "Close anyway?" 103 | msgstr "已開啟數個分頁。是否關閉?" 104 | 105 | #: src/callbacks.c:297 src/callbacks.c:308 106 | msgid "Tab name" 107 | msgstr "分頁名稱" 108 | 109 | #: src/termit_preferences.c:187 110 | #, fuzzy 111 | msgid "Title" 112 | msgstr "檔案" 113 | 114 | #: src/sessions.c:90 115 | #, c-format 116 | msgid "Unable to create directory '%s': %s" 117 | msgstr "無法建立目錄 '%s': %s" 118 | 119 | #~ msgid "Bookmarks" 120 | #~ msgstr "書籤" 121 | 122 | #~ msgid "Encoding" 123 | #~ msgstr "編碼" 124 | 125 | #~ msgid "Select font" 126 | #~ msgstr "選擇字型" 127 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright © 2007-2023 Evgeny Ratnikov 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | SET(TARGET "termit") 17 | 18 | INCLUDE_DIRECTORIES(${TERMIT_SOURCE_DIR}) 19 | 20 | INCLUDE (FindPkgConfig) 21 | 22 | pkg_search_module(GTK REQUIRED gtk+-3.0>=3.22) 23 | pkg_search_module(VTE REQUIRED libvte>=0.68 vte>=0.68 vte-2.91>=0.68) 24 | IF(NOT VTE_FOUND) 25 | message(FATAL_ERROR "Vte library was not found.") 26 | ENDIF(NOT VTE_FOUND) 27 | 28 | SET(LUA_VERSION "" CACHE STRING "Lua version") 29 | IF(LUA_VERSION STREQUAL "") 30 | IF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 31 | pkg_search_module(LUA REQUIRED lua54) 32 | ELSE(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 33 | pkg_search_module(LUA REQUIRED lua>=5.4 lua5.4) 34 | ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 35 | ELSE(LUA_VERSION STREQUAL "") 36 | pkg_search_module(LUA REQUIRED 37 | lua=${LUA_VERSION} lua5.4=${LUA_VERSION}) 38 | ENDIF(LUA_VERSION STREQUAL "") 39 | IF(NOT LUA_FOUND) 40 | message(FATAL_ERROR "Lua library was not found.") 41 | ENDIF(NOT LUA_FOUND) 42 | 43 | INCLUDE(Sources.cmake) 44 | 45 | SET(TERMIT_CFLAGS "") 46 | IF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 47 | SET(TERMIT_CFLAGS "${TERMIT_CFLAGS} -I/usr/local/include") 48 | ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 49 | FOREACH(cflag ${VTE_CFLAGS} ${GTK_CFLAGS} ${LUA_CFLAGS}) 50 | SET(TERMIT_CFLAGS "${TERMIT_CFLAGS} ${cflag}") 51 | ENDFOREACH(cflag) 52 | 53 | IF(DEBUG) 54 | SET(EXTRA_CFLAGS "-std=c99 -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter") 55 | SET(TERMIT_CFLAGS "${TERMIT_CFLAGS} ${EXTRA_CFLAGS} -g -DDEBUG -DGTK_DISABLE_DEPRECATED") 56 | ELSE(DEBUG) 57 | SET(TERMIT_CFLAGS "${TERMIT_CFLAGS} -O2") 58 | ENDIF(DEBUG) 59 | 60 | set(TERMIT_LDFLAGS ${VTE_LDFLAGS} ${GTK_LDFLAGS}) 61 | 62 | SET_SOURCE_FILES_PROPERTIES(${TERMIT_SRCS} PROPERTIES 63 | COMPILE_FLAGS "${TERMIT_CFLAGS}") 64 | 65 | ADD_EXECUTABLE(${TARGET} ${TERMIT_SRCS}) 66 | 67 | IF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 68 | SET(TERMIT_LDFLAGS"-llua5.4") 69 | ELSE(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 70 | SET(TERMIT_LDFLAGS "-ldl -lm") 71 | ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") 72 | FOREACH(ldflag ${VTE_LDFLAGS} ${LUA_LDFLAGS}) 73 | LIST(APPEND TERMIT_LDFLAGS "${ldflag}") 74 | ENDFOREACH(ldflag) 75 | LIST(APPEND TERMIT_LDFLAGS "-lX11") 76 | 77 | target_link_libraries(${TARGET} ${TERMIT_LDFLAGS}) 78 | 79 | INSTALL(TARGETS ${TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) 80 | 81 | -------------------------------------------------------------------------------- /src/Sources.cmake: -------------------------------------------------------------------------------- 1 | # Copyright © 2007-2023 Evgeny Ratnikov 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | SET( TERMIT_SRCS 17 | termit.c termit_core_api.c callbacks.c sessions.c 18 | keybindings.c lua_conf.c lua_api.c configs.c 19 | termit_style.c termit_preferences.c 20 | ) 21 | SET( TERMIT_HDRS 22 | termit_core_api.h callbacks.h configs.h sessions.h 23 | keybindings.h lua_api.h termit.h termit_style.h 24 | ) 25 | -------------------------------------------------------------------------------- /src/callbacks.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "termit.h" 23 | #include "configs.h" 24 | #include "sessions.h" 25 | #include "termit_core_api.h" 26 | #include "termit_style.h" 27 | #include "lua_api.h" 28 | #include "keybindings.h" 29 | #include "callbacks.h" 30 | 31 | static gboolean confirm_exit() 32 | { 33 | if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(termit.notebook)) <= 1) { 34 | return FALSE; 35 | } 36 | 37 | GtkWidget *dlg = gtk_message_dialog_new( 38 | GTK_WINDOW(termit.main_window), 39 | GTK_DIALOG_MODAL, 40 | GTK_MESSAGE_QUESTION, 41 | GTK_BUTTONS_YES_NO, _("Several tabs are opened.\nClose anyway?")); 42 | gint response = gtk_dialog_run(GTK_DIALOG(dlg)); 43 | gtk_widget_destroy(dlg); 44 | return (response == GTK_RESPONSE_YES) ? FALSE : TRUE; 45 | } 46 | 47 | gboolean termit_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) 48 | { 49 | return confirm_exit(); 50 | } 51 | 52 | void termit_on_destroy(GtkWidget *widget, gpointer data) 53 | { 54 | termit_quit(); 55 | } 56 | 57 | void termit_on_tab_title_changed(VteTerminal *vte, gpointer user_data) 58 | { 59 | if (!configs.allow_changing_title) { 60 | return; 61 | } 62 | gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(termit.notebook)); 63 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return); 64 | 65 | if (pTab->custom_tab_name) { 66 | return; 67 | } 68 | 69 | const char* title = vte_terminal_get_window_title(vte); 70 | if (title) { 71 | termit_tab_set_title(pTab, title); 72 | } 73 | } 74 | 75 | void termit_on_tab_close_clicked(GtkButton* btn, gpointer user_data) 76 | { 77 | struct TermitTab* pTab = (struct TermitTab*)user_data; 78 | TRACE("termit_close_tab %p", pTab); 79 | if (pTab == NULL) { 80 | TRACE("pTab is empty"); 81 | return; 82 | } 83 | gint sz = gtk_notebook_get_n_pages(GTK_NOTEBOOK(termit.notebook)); 84 | for (gint p = 0; p < sz; ++p) { 85 | struct TermitTab* tt = termit_get_tab_by_index(p); 86 | if (tt == pTab) { 87 | termit_del_tab_n(p); 88 | break; 89 | } 90 | } 91 | if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(termit.notebook)) == 0) { 92 | termit_quit(); 93 | } 94 | } 95 | 96 | gboolean termit_on_search_keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 97 | { 98 | switch (event->keyval) { 99 | case GDK_KEY_Return: { 100 | if (event->state == GDK_CONTROL_MASK) { 101 | termit_on_find_prev(NULL, NULL); 102 | } else { 103 | termit_on_find_next(NULL, NULL); 104 | } 105 | return TRUE; 106 | } 107 | case GDK_KEY_Escape: { 108 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(termit.b_toggle_search), FALSE); 109 | return TRUE; 110 | } 111 | default: 112 | return FALSE; 113 | } 114 | return FALSE; 115 | } 116 | 117 | static void termit_search_prepare_regex(const gchar* searchRegex) 118 | { 119 | gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(termit.notebook)); 120 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return); 121 | if (strlen(searchRegex) == 0) { 122 | VteRegex* regex = vte_terminal_search_get_regex(VTE_TERMINAL(pTab->vte)); 123 | if (regex) { 124 | vte_regex_unref(regex); 125 | } 126 | vte_terminal_search_set_regex(VTE_TERMINAL(pTab->vte), NULL, 0); 127 | } else { 128 | VteRegex* currSearchRegex = vte_terminal_search_get_regex(VTE_TERMINAL(pTab->vte)); 129 | if (currSearchRegex && strcmp(pTab->search_regex, searchRegex) == 0) { 130 | return; 131 | } 132 | if (currSearchRegex) { 133 | vte_regex_unref(currSearchRegex); 134 | } 135 | if (pTab->search_regex) { 136 | g_free(pTab->search_regex); 137 | } 138 | GError* err = NULL; 139 | VteRegex* regex = vte_regex_new_for_search(searchRegex, -1, VTE_REGEX_FLAGS_DEFAULT, &err); 140 | if (err) { 141 | TRACE("failed to compile regex [%s]: skipping", searchRegex); 142 | return; 143 | } 144 | vte_terminal_search_set_regex(VTE_TERMINAL(pTab->vte), regex, 0); 145 | pTab->search_regex = g_strdup(searchRegex); 146 | } 147 | } 148 | 149 | void termit_on_find_next(GtkButton* btn, gpointer user_data) 150 | { 151 | termit_search_prepare_regex(gtk_entry_get_text(GTK_ENTRY(termit.search_entry))); 152 | termit_search_find_next(); 153 | } 154 | 155 | void termit_on_find_prev(GtkButton* btn, gpointer user_data) 156 | { 157 | termit_search_prepare_regex(gtk_entry_get_text(GTK_ENTRY(termit.search_entry))); 158 | termit_search_find_prev(); 159 | } 160 | 161 | void termit_on_toggle_search(GtkToggleButton* tb, gpointer user_data) 162 | { 163 | termit_toggle_search(); 164 | } 165 | 166 | void termit_on_toggle_scrollbar() 167 | { 168 | TRACE_MSG(__FUNCTION__); 169 | gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(termit.notebook)); 170 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return); 171 | 172 | if (pTab->scrollbar_is_shown) { 173 | gtk_widget_hide(GTK_WIDGET(pTab->scrollbar)); 174 | } else { 175 | gtk_widget_show(GTK_WIDGET(pTab->scrollbar)); 176 | } 177 | pTab->scrollbar_is_shown = !pTab->scrollbar_is_shown; 178 | } 179 | 180 | void termit_on_child_exited(VteTerminal* vte, gint status, gpointer user_data) 181 | { 182 | gint page = -1; 183 | struct TermitTab* pTab = termit_get_tab_by_vte(vte, &page); 184 | if (!pTab) { 185 | return; 186 | } 187 | TRACE("child process exited with status %d", status); 188 | termit_del_tab_n(page); 189 | if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(termit.notebook)) == 0) { 190 | TRACE("no pages left, exiting"); 191 | termit_quit(); 192 | } 193 | } 194 | 195 | static int termit_cursor_under_match(GdkEvent* ev, char** matchedText) 196 | { 197 | gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(termit.notebook)); 198 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return -1); 199 | int tag = -1; 200 | *matchedText = vte_terminal_match_check_event(VTE_TERMINAL(pTab->vte), ev, &tag); 201 | return tag; 202 | } 203 | 204 | static struct Match* get_match_by_tag(GArray* matches, int tag) 205 | { 206 | guint i = 0; 207 | for (; ilen; ++i) { 208 | struct Match* match = &g_array_index(matches, struct Match, i); 209 | if (match->tag == tag) { 210 | return match; 211 | } 212 | } 213 | return NULL; 214 | } 215 | 216 | gboolean termit_on_popup(GtkWidget *widget, GdkEvent *event) 217 | { 218 | if (event->type != GDK_BUTTON_PRESS) { 219 | return FALSE; 220 | } 221 | 222 | GdkEventButton *event_button = (GdkEventButton *) event; 223 | if (event_button->button == 3) { 224 | GtkMenu *menu = GTK_MENU(termit.menu); 225 | gtk_menu_popup_at_pointer(menu, NULL); 226 | return TRUE; 227 | } else if (event_button->button == 1) { 228 | gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(termit.notebook)); 229 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return FALSE); 230 | char* matchedText = NULL; 231 | int matchTag = termit_cursor_under_match(event, &matchedText); 232 | if (!matchedText) { 233 | return FALSE; 234 | } 235 | struct Match* match = get_match_by_tag(pTab->matches, matchTag); 236 | if (!match) { 237 | g_free(matchedText); 238 | return FALSE; 239 | } 240 | TRACE("tag=%d match=[%s]", matchTag, match->pattern); 241 | termit_lua_domatch(match->lua_callback, matchedText); 242 | g_free(matchedText); 243 | } 244 | 245 | return FALSE; 246 | } 247 | 248 | static gboolean dlg_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 249 | { 250 | switch (event->keyval) { 251 | case GDK_KEY_Return: 252 | g_signal_emit_by_name(widget, "response", GTK_RESPONSE_ACCEPT, NULL); 253 | break; 254 | case GDK_KEY_Escape: 255 | g_signal_emit_by_name(widget, "response", GTK_RESPONSE_REJECT, NULL); 256 | break; 257 | default: 258 | return FALSE; 259 | } 260 | return TRUE; 261 | } 262 | 263 | void termit_on_beep(VteTerminal *vte, gpointer user_data) 264 | { 265 | struct TermitTab* pTab = (struct TermitTab*)user_data; 266 | if (!pTab) { 267 | ERROR("pTab is NULL"); 268 | return; 269 | } 270 | if (!gtk_window_has_toplevel_focus(GTK_WINDOW(termit.main_window))) { 271 | if (configs.urgency_on_bell) { 272 | gtk_window_set_urgency_hint(GTK_WINDOW(termit.main_window), TRUE); 273 | GtkWidget* label = gtk_box_get_center_widget(GTK_BOX(pTab->tab_name)); 274 | gchar* marked_title = g_strdup_printf("%s", gtk_label_get_text(GTK_LABEL(label))); 275 | gtk_label_set_markup(GTK_LABEL(label), marked_title); 276 | g_free(marked_title); 277 | } 278 | } 279 | } 280 | 281 | gboolean termit_on_focus(GtkWidget *widget, GtkDirectionType arg1, gpointer user_data) 282 | { 283 | struct TermitTab* pTab = (struct TermitTab*)user_data; 284 | if (!pTab) { 285 | ERROR("pTab is NULL"); 286 | return FALSE; 287 | } 288 | if (gtk_window_get_urgency_hint(GTK_WINDOW(termit.main_window))) { 289 | gtk_window_set_urgency_hint(GTK_WINDOW(termit.main_window), FALSE); 290 | GtkWidget* label = gtk_box_get_center_widget(GTK_BOX(pTab->tab_name)); 291 | gtk_label_set_markup(GTK_LABEL(label), gtk_label_get_text(GTK_LABEL(label))); 292 | gtk_label_set_use_markup(GTK_LABEL(label), FALSE); 293 | } 294 | return FALSE; 295 | } 296 | 297 | void termit_on_set_tab_name() 298 | { 299 | GtkWidget *dlg = gtk_dialog_new_with_buttons( 300 | _("Tab name"), 301 | GTK_WINDOW(termit.main_window), 302 | GTK_DIALOG_MODAL, 303 | "_Cancel", GTK_RESPONSE_REJECT, 304 | "_OK", GTK_RESPONSE_ACCEPT, 305 | NULL); 306 | gtk_dialog_set_default_response(GTK_DIALOG(dlg), GTK_RESPONSE_ACCEPT); 307 | gtk_window_set_modal(GTK_WINDOW(dlg), TRUE); 308 | 309 | gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(termit.notebook)); 310 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return); 311 | GtkWidget *label = gtk_label_new(_("Tab name")); 312 | GtkWidget *entry = gtk_entry_new(); 313 | gtk_entry_set_text( 314 | GTK_ENTRY(entry), 315 | gtk_notebook_get_tab_label_text(GTK_NOTEBOOK(termit.notebook), pTab->hbox)); 316 | 317 | GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 318 | gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); 319 | gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); 320 | 321 | g_signal_connect(G_OBJECT(dlg), "key-press-event", G_CALLBACK(dlg_key_press), dlg); 322 | 323 | gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg))), hbox, FALSE, FALSE, 10); 324 | gtk_widget_show_all(dlg); 325 | 326 | if (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dlg))) { 327 | termit_tab_set_title(pTab, gtk_entry_get_text(GTK_ENTRY(entry))); 328 | pTab->custom_tab_name = TRUE; 329 | } 330 | gtk_widget_destroy(dlg); 331 | } 332 | 333 | void termit_preferences_dialog(struct TermitTab *style); 334 | 335 | void termit_on_edit_preferences() 336 | { 337 | gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(termit.notebook)); 338 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return); 339 | termit_preferences_dialog(pTab); 340 | } 341 | 342 | void termit_on_exit() 343 | { 344 | if (confirm_exit() == FALSE) { 345 | termit_quit(); 346 | } 347 | } 348 | 349 | void termit_on_switch_page(GtkNotebook *notebook, gpointer arg, guint page, gpointer user_data) 350 | { 351 | TERMIT_GET_TAB_BY_INDEX(pTab, page, return); 352 | TRACE("%s page=%d vte=%p", __FUNCTION__, page, pTab->vte); 353 | // it seems that set_active eventually calls toggle callback 354 | /*((GtkCheckMenuItem*)termit.mi_show_scrollbar)->active = pTab->scrollbar_is_shown;*/ 355 | gpointer pHandlerId = g_object_get_data(G_OBJECT(termit.mi_show_scrollbar), "handlerId"); 356 | if (pHandlerId) { 357 | g_signal_handler_disconnect(G_OBJECT(termit.mi_show_scrollbar), *((gulong*)pHandlerId)); 358 | } 359 | gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(termit.mi_show_scrollbar), pTab->scrollbar_is_shown); 360 | termit_set_show_scrollbar_signal(termit.mi_show_scrollbar, pHandlerId); 361 | 362 | termit_set_statusbar_message(page); 363 | if (configs.allow_changing_title) { 364 | termit_set_window_title(pTab->title); 365 | } 366 | } 367 | 368 | gint termit_on_double_click(GtkWidget *widget, GdkEventButton *event, gpointer func_data) 369 | { 370 | termit_mouse_event(event); 371 | return FALSE; 372 | } 373 | 374 | static gchar* termit_get_xdg_data_path() 375 | { 376 | gchar* fullPath = NULL; 377 | const gchar *dataHome = g_getenv("XDG_DATA_HOME"); 378 | if (dataHome) { 379 | fullPath = g_strdup_printf("%s/termit", dataHome); 380 | } else { 381 | fullPath = g_strdup_printf("%s/.local/share/termit", g_getenv("HOME")); 382 | } 383 | TRACE("XDG_DATA_PATH=%s", fullPath); 384 | return fullPath; 385 | } 386 | 387 | void termit_on_save_session() 388 | { 389 | gchar* fullPath = termit_get_xdg_data_path(); 390 | GtkWidget* dlg = gtk_file_chooser_dialog_new( 391 | _("Save session"), 392 | GTK_WINDOW(termit.main_window), 393 | GTK_FILE_CHOOSER_ACTION_SAVE, 394 | "_Cancel", GTK_RESPONSE_REJECT, 395 | "_Save", GTK_RESPONSE_ACCEPT, 396 | NULL); 397 | gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dlg), TRUE); 398 | 399 | gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dlg), fullPath); 400 | gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dlg), "New session"); 401 | 402 | if (gtk_dialog_run(GTK_DIALOG(dlg)) != GTK_RESPONSE_ACCEPT) { 403 | gtk_widget_destroy(dlg); 404 | g_free(fullPath); 405 | return; 406 | } 407 | 408 | gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg)); 409 | termit_save_session(filename); 410 | 411 | g_free(filename); 412 | gtk_widget_destroy(dlg); 413 | g_free(fullPath); 414 | } 415 | 416 | void termit_on_load_session() 417 | { 418 | gchar* fullPath = termit_get_xdg_data_path(); 419 | 420 | GtkWidget* dlg = gtk_file_chooser_dialog_new( 421 | _("Open session"), 422 | GTK_WINDOW(termit.main_window), 423 | GTK_FILE_CHOOSER_ACTION_OPEN, 424 | "_Cancel", GTK_RESPONSE_REJECT, 425 | "_OK", GTK_RESPONSE_ACCEPT, 426 | NULL); 427 | gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dlg), TRUE); 428 | gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dlg), fullPath); 429 | 430 | if (gtk_dialog_run(GTK_DIALOG(dlg)) != GTK_RESPONSE_ACCEPT) { 431 | goto free_dlg; 432 | } 433 | 434 | gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg)); 435 | termit_load_session(filename); 436 | g_free(filename); 437 | free_dlg: 438 | gtk_widget_destroy(dlg); 439 | g_free(fullPath); 440 | } 441 | 442 | void termit_on_menu_item_selected(GtkWidget *widget, void *data) 443 | { 444 | struct UserMenuItem* pMi = (struct UserMenuItem*)g_object_get_data(G_OBJECT(widget), 445 | TERMIT_USER_MENU_ITEM_DATA); 446 | if (pMi && pMi->lua_callback) { 447 | termit_lua_dofunction(pMi->lua_callback); 448 | } 449 | } 450 | 451 | gboolean termit_on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 452 | { 453 | return termit_key_event(event); 454 | } 455 | -------------------------------------------------------------------------------- /src/callbacks.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_CALLBACKS_H 18 | #define TERMIT_CALLBACKS_H 19 | 20 | gboolean termit_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data); 21 | void termit_on_destroy(GtkWidget *widget, gpointer data); 22 | gboolean termit_on_popup(GtkWidget *, GdkEvent *); 23 | gboolean termit_on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data); 24 | gboolean termit_on_focus(GtkWidget *widget, GtkDirectionType arg1, gpointer user_data); 25 | void termit_on_beep(VteTerminal *vte, gpointer user_data); 26 | void termit_on_edit_preferences(); 27 | void termit_on_set_tab_name(); 28 | void termit_on_toggle_scrollbar(); 29 | void termit_on_child_exited(VteTerminal*, gint, gpointer); 30 | void termit_on_exit(); 31 | void termit_on_switch_page(GtkNotebook *notebook, gpointer arg, guint page, gpointer user_data); 32 | void termit_on_menu_item_selected(GtkWidget *widget, void *data); 33 | gint termit_on_double_click(GtkWidget *widget, GdkEventButton *event, gpointer func_data); 34 | void termit_on_save_session(); 35 | void termit_on_load_session(); 36 | void termit_on_tab_title_changed(VteTerminal *vte, gpointer user_data); 37 | void termit_on_tab_close_clicked(GtkButton*, gpointer); 38 | void termit_on_toggle_search(GtkToggleButton*, gpointer); 39 | void termit_on_find_next(GtkButton*, gpointer); 40 | void termit_on_find_prev(GtkButton*, gpointer); 41 | gboolean termit_on_search_keypress(GtkWidget *widget, GdkEventKey *event, gpointer user_data); 42 | 43 | #endif /* TERMIT_CALLBACKS_H */ 44 | -------------------------------------------------------------------------------- /src/configs.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include "termit.h" 21 | #include "keybindings.h" 22 | #include "configs.h" 23 | #include "lua_api.h" 24 | 25 | struct Configs configs = {}; 26 | 27 | static struct { 28 | const char* name; 29 | VteEraseBinding val; 30 | } erase_bindings[] = { 31 | {"Auto", VTE_ERASE_AUTO}, 32 | {"AsciiBksp", VTE_ERASE_ASCII_BACKSPACE}, 33 | {"AsciiDel", VTE_ERASE_ASCII_DELETE}, 34 | {"EraseDel", VTE_ERASE_DELETE_SEQUENCE}, 35 | {"EraseTty", VTE_ERASE_TTY} 36 | }; 37 | static guint EraseBindingsSz = sizeof(erase_bindings)/sizeof(erase_bindings[0]); 38 | 39 | const char* termit_erase_binding_to_string(VteEraseBinding val) 40 | { 41 | return erase_bindings[val].name; 42 | } 43 | 44 | VteEraseBinding termit_erase_binding_from_string(const char* str) 45 | { 46 | guint i = 0; 47 | for (; i < EraseBindingsSz; ++i) { 48 | if (strcmp(str, erase_bindings[i].name) == 0) { 49 | return erase_bindings[i].val; 50 | } 51 | } 52 | ERROR("unknown erase binding [%s], using Auto", str); 53 | return VTE_ERASE_AUTO; 54 | } 55 | 56 | static struct { 57 | const char* name; 58 | VteCursorBlinkMode val; 59 | } cursor_blink_modes[] = { 60 | {"System", VTE_CURSOR_BLINK_SYSTEM}, 61 | {"BlinkOn", VTE_CURSOR_BLINK_ON}, 62 | {"BlinkOff", VTE_CURSOR_BLINK_OFF} 63 | }; 64 | static guint BlinkModesSz = sizeof(cursor_blink_modes)/sizeof(cursor_blink_modes[0]); 65 | 66 | const char* termit_cursor_blink_mode_to_string(VteCursorBlinkMode val) 67 | { 68 | return cursor_blink_modes[val].name; 69 | } 70 | 71 | VteCursorBlinkMode termit_cursor_blink_mode_from_string(const char* str) 72 | { 73 | guint i = 0; 74 | for (; i < BlinkModesSz; ++i) { 75 | if (strcmp(str, cursor_blink_modes[i].name) == 0) { 76 | return cursor_blink_modes[i].val; 77 | } 78 | } 79 | ERROR("unknown blink mode [%s], using System", str); 80 | return VTE_CURSOR_BLINK_SYSTEM; 81 | } 82 | 83 | static struct { 84 | const char* name; 85 | VteCursorShape val; 86 | } cursor_shapes[] = { 87 | {"Block", VTE_CURSOR_SHAPE_BLOCK}, 88 | {"Ibeam", VTE_CURSOR_SHAPE_IBEAM}, 89 | {"Underline", VTE_CURSOR_SHAPE_UNDERLINE} 90 | }; 91 | static guint ShapesSz = sizeof(cursor_shapes)/sizeof(cursor_shapes[0]); 92 | 93 | const char* termit_cursor_shape_to_string(VteCursorShape val) 94 | { 95 | return cursor_shapes[val].name; 96 | } 97 | 98 | VteCursorShape termit_cursor_shape_from_string(const char* str) 99 | { 100 | guint i = 0; 101 | for (; i < ShapesSz; ++i) { 102 | if (strcmp(str, cursor_shapes[i].name) == 0) { 103 | return cursor_shapes[i].val; 104 | } 105 | } 106 | ERROR("unknown cursor shape [%s], using Block", str); 107 | return VTE_CURSOR_SHAPE_BLOCK; 108 | } 109 | 110 | void termit_config_trace() 111 | { 112 | #ifdef DEBUG 113 | TRACE(" default_window_title = %s", configs.default_window_title); 114 | TRACE(" default_tab_name = %s", configs.default_tab_name); 115 | TRACE(" default_encoding = %s", configs.default_encoding); 116 | TRACE(" default_word_char_exceptions = %s", configs.default_word_char_exceptions); 117 | TRACE(" show_scrollbar = %d", configs.show_scrollbar); 118 | TRACE(" hide_menubar = %d", configs.hide_menubar); 119 | TRACE(" hide_tabbar = %d", configs.hide_tabbar); 120 | TRACE(" fill_tabbar = %d", configs.fill_tabbar); 121 | TRACE(" show_border = %d", configs.show_border); 122 | TRACE(" hide_single_tab = %d", configs.hide_single_tab); 123 | TRACE(" start_maximized = %d", configs.start_maximized); 124 | TRACE(" hide_titlebar_when_maximized = %d", configs.hide_titlebar_when_maximized); 125 | TRACE(" scrollback_lines = %d", configs.scrollback_lines); 126 | TRACE(" cols x rows = %d x %d", configs.cols, configs.rows); 127 | TRACE(" backspace = %s", termit_erase_binding_to_string(configs.default_bksp)); 128 | TRACE(" delete = %s", termit_erase_binding_to_string(configs.default_delete)); 129 | TRACE(" blink = %s", termit_cursor_blink_mode_to_string(configs.default_blink)); 130 | TRACE(" shape = %s", termit_cursor_shape_to_string(configs.default_shape)); 131 | TRACE(" allow_changing_title = %d", configs.allow_changing_title); 132 | TRACE(" audible_bell = %d", configs.audible_bell); 133 | TRACE(" scroll_on_output = %d", configs.scroll_on_output); 134 | TRACE(" scroll_on_keystroke = %d", configs.scroll_on_keystroke); 135 | TRACE(" get_window_title_callback = %d", configs.get_window_title_callback); 136 | TRACE(" get_tab_title_callback = %d", configs.get_tab_title_callback); 137 | TRACE(" get_statusbar_callback = %d", configs.get_statusbar_callback); 138 | TRACE(" kb_policy = %d", configs.kb_policy); 139 | TRACE(" tab_pos = %d", configs.tab_pos); 140 | TRACE(" tab_close_button = %d", configs.tab_close_button); 141 | TRACE(" style:"); 142 | TRACE(" font_name = %s", configs.style.font_name); 143 | if (configs.style.foreground_color) { 144 | gchar* tmpStr = gdk_rgba_to_string(configs.style.foreground_color); 145 | TRACE(" foreground_color = %s", tmpStr); 146 | g_free(tmpStr); 147 | } 148 | if (configs.style.background_color) { 149 | gchar* tmpStr = gdk_rgba_to_string(configs.style.background_color); 150 | TRACE(" background_color = %s", tmpStr); 151 | g_free(tmpStr); 152 | } 153 | #endif 154 | } 155 | 156 | void termit_configs_set_defaults() 157 | { 158 | configs.default_window_title = g_strdup("Termit"); 159 | configs.default_tab_name = g_strdup("Terminal"); 160 | termit_style_init(&configs.style); 161 | configs.default_command = g_strdup(g_getenv("SHELL")); 162 | configs.default_encoding = g_strdup("UTF-8"); 163 | configs.default_word_char_exceptions = g_strdup("-A-Za-z0-9,./?%_~"); 164 | configs.scrollback_lines = 4096; 165 | configs.cols = 80; 166 | configs.rows = 24; 167 | configs.default_bksp = VTE_ERASE_AUTO; 168 | configs.default_delete = VTE_ERASE_AUTO; 169 | configs.default_blink = VTE_CURSOR_BLINK_SYSTEM; 170 | configs.default_shape = VTE_CURSOR_SHAPE_BLOCK; 171 | 172 | configs.user_menus = g_array_new(FALSE, TRUE, sizeof(struct UserMenu)); 173 | configs.user_popup_menus = g_array_new(FALSE, TRUE, sizeof(struct UserMenu)); 174 | configs.key_bindings = g_array_new(FALSE, TRUE, sizeof(struct KeyBinding)); 175 | configs.mouse_bindings = g_array_new(FALSE, TRUE, sizeof(struct MouseBinding)); 176 | configs.matches = g_array_new(FALSE, TRUE, sizeof(struct Match)); 177 | 178 | configs.start_maximized = FALSE; 179 | configs.hide_titlebar_when_maximized = FALSE; 180 | configs.hide_single_tab = FALSE; 181 | configs.show_scrollbar = TRUE; 182 | configs.fill_tabbar = FALSE; 183 | configs.hide_menubar = FALSE; 184 | configs.hide_tabbar = FALSE; 185 | configs.show_border = TRUE; 186 | configs.allow_changing_title = FALSE; 187 | configs.audible_bell = FALSE; 188 | configs.urgency_on_bell = FALSE; 189 | configs.get_window_title_callback = 0; 190 | configs.get_tab_title_callback = 0; 191 | configs.get_statusbar_callback = 0; 192 | configs.kb_policy = TermitKbUseKeysym; 193 | configs.tab_pos = GTK_POS_TOP; 194 | configs.tab_close_button = FALSE; 195 | configs.scroll_on_output = FALSE; 196 | configs.scroll_on_keystroke = TRUE; 197 | } 198 | 199 | static void free_menu(GArray* menus) 200 | { 201 | guint i = 0; 202 | for (; ilen; ++i) { 203 | struct UserMenu* um = &g_array_index(menus, struct UserMenu, i); 204 | guint j = 0; 205 | for (; jitems->len; ++j) { 206 | struct UserMenuItem* umi = &g_array_index(um->items, struct UserMenuItem, j); 207 | g_free(umi->name); 208 | g_free(umi->accel); 209 | termit_lua_unref(&umi->lua_callback); 210 | } 211 | g_free(um->name); 212 | g_array_free(um->items, TRUE); 213 | } 214 | } 215 | 216 | void termit_config_deinit() 217 | { 218 | g_free(configs.default_window_title); 219 | g_free(configs.default_tab_name); 220 | termit_style_free(&configs.style); 221 | g_free(configs.default_command); 222 | g_free(configs.default_encoding); 223 | g_free(configs.default_word_char_exceptions); 224 | 225 | free_menu(configs.user_menus); 226 | g_array_free(configs.user_menus, TRUE); 227 | free_menu(configs.user_popup_menus); 228 | g_array_free(configs.user_popup_menus, TRUE); 229 | 230 | // name and default_binding are static (e.g. can be in readonly mempage) 231 | guint i = 0; 232 | for (; ilen; ++i) { 233 | struct KeyBinding* kb = &g_array_index(configs.key_bindings, struct KeyBinding, i); 234 | termit_lua_unref(&kb->lua_callback); 235 | } 236 | g_array_free(configs.key_bindings, TRUE); 237 | 238 | i = 0; 239 | for (; ilen; ++i) { 240 | struct MouseBinding* mb = &g_array_index(configs.mouse_bindings, struct MouseBinding, i); 241 | termit_lua_unref(&mb->lua_callback); 242 | } 243 | g_array_free(configs.mouse_bindings, TRUE); 244 | 245 | i = 0; 246 | for (; ilen; ++i) { 247 | struct Match* match = &g_array_index(configs.matches, struct Match, i); 248 | vte_regex_unref(match->regex); 249 | g_free(match->pattern); 250 | } 251 | g_array_free(configs.matches, TRUE); 252 | 253 | termit_lua_unref(&configs.get_window_title_callback); 254 | termit_lua_unref(&configs.get_tab_title_callback); 255 | termit_lua_unref(&configs.get_statusbar_callback); 256 | } 257 | -------------------------------------------------------------------------------- /src/configs.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_CONFIGS_H 18 | #define TERMIT_CONFIGS_H 19 | 20 | #include 21 | #include 22 | 23 | #include "termit_style.h" 24 | 25 | enum TermitKbPolicy {TermitKbUseKeycode = 1, TermitKbUseKeysym = 2}; 26 | 27 | struct Configs 28 | { 29 | gchar* default_window_title; 30 | gchar* default_tab_name; 31 | gchar* default_command; 32 | gchar* default_encoding; 33 | gchar* default_word_char_exceptions; 34 | guint scrollback_lines; 35 | guint cols; 36 | guint rows; 37 | VteEraseBinding default_bksp; 38 | VteEraseBinding default_delete; 39 | VteCursorBlinkMode default_blink; 40 | VteCursorShape default_shape; 41 | GArray* user_menus; // UserMenu 42 | GArray* user_popup_menus; // UserMenu 43 | GArray* key_bindings; // KeyBinding 44 | GArray* mouse_bindings; // MouseBinding 45 | GArray* matches; // Match 46 | gboolean start_maximized; 47 | gboolean hide_titlebar_when_maximized; 48 | gboolean hide_single_tab; 49 | gboolean show_scrollbar; 50 | gboolean hide_menubar; 51 | gboolean hide_tabbar; 52 | gboolean fill_tabbar; 53 | gboolean show_border; 54 | gboolean urgency_on_bell; 55 | gboolean allow_changing_title; 56 | gboolean audible_bell; 57 | gboolean scroll_on_output; 58 | gboolean scroll_on_keystroke; 59 | int get_window_title_callback; 60 | int get_tab_title_callback; 61 | int get_statusbar_callback; 62 | enum TermitKbPolicy kb_policy; 63 | GtkPositionType tab_pos; 64 | gboolean tab_close_button; 65 | struct TermitStyle style; 66 | GArray* default_tabs; // TabInfo 67 | }; 68 | 69 | struct Match 70 | { 71 | gchar* pattern; 72 | VteRegex* regex; 73 | guint32 flags; 74 | int tag; 75 | int lua_callback; 76 | }; 77 | struct UserMenuItem 78 | { 79 | gchar* name; 80 | gchar* accel; 81 | int lua_callback; 82 | }; 83 | struct UserMenu 84 | { 85 | gchar* name; 86 | GArray* items; // UserMenuItem 87 | }; 88 | 89 | extern struct Configs configs; 90 | 91 | void termit_config_deinit(); 92 | void termit_configs_set_defaults(); 93 | void termit_config_load(); 94 | 95 | void termit_config_trace(); 96 | void termit_keys_trace(); 97 | 98 | const char* termit_erase_binding_to_string(VteEraseBinding val); 99 | VteEraseBinding termit_erase_binding_from_string(const char* str); 100 | 101 | const char* termit_cursor_blink_mode_to_string(VteCursorBlinkMode val); 102 | VteCursorBlinkMode termit_cursor_blink_mode_from_string(const char* str); 103 | 104 | const char* termit_cursor_shape_to_string(VteCursorShape val); 105 | VteCursorShape termit_cursor_shape_from_string(const char* str); 106 | 107 | #define TERMIT_USER_MENU_ITEM_DATA "termit.umi_data" 108 | #define TERMIT_TAB_DATA "termit.tab_data" 109 | 110 | #endif /* TERMIT_CONFIGS_H */ 111 | -------------------------------------------------------------------------------- /src/keybindings.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "termit.h" 27 | #include "configs.h" 28 | #include "termit_core_api.h" 29 | #include "lua_api.h" 30 | #include "keybindings.h" 31 | 32 | extern lua_State* L; 33 | 34 | static Display* disp; 35 | 36 | void termit_keys_trace() 37 | { 38 | #ifdef DEBUG 39 | guint i = 0; 40 | for (; ilen; ++i) { 41 | struct KeyBinding* kb = &g_array_index(configs.key_bindings, struct KeyBinding, i); 42 | TRACE("%s: %d, %d(%ld)", kb->name, kb->kws.state, kb->kws.keyval, kb->keycode); 43 | } 44 | #endif 45 | } 46 | #define ADD_DEFAULT_KEYBINDING(keybinding_, lua_callback_) \ 47 | { \ 48 | lua_getglobal(ls, lua_callback_); \ 49 | int func = luaL_ref(ls, LUA_REGISTRYINDEX); \ 50 | termit_keys_bind(keybinding_, func); \ 51 | } 52 | 53 | void termit_keys_set_defaults() 54 | { 55 | lua_State* ls = L; 56 | disp = XOpenDisplay(NULL); 57 | ADD_DEFAULT_KEYBINDING("Alt-Left", "prevTab"); 58 | ADD_DEFAULT_KEYBINDING("Alt-Right", "nextTab"); 59 | ADD_DEFAULT_KEYBINDING("Ctrl-t", "openTab"); 60 | ADD_DEFAULT_KEYBINDING("CtrlShift-w", "closeTab"); 61 | ADD_DEFAULT_KEYBINDING("Ctrl-Insert", "copy"); 62 | ADD_DEFAULT_KEYBINDING("Shift-Insert", "paste"); 63 | // push func to stack, get ref 64 | termit_keys_trace(); 65 | } 66 | 67 | struct TermitModifier { 68 | const gchar* name; 69 | guint state; 70 | }; 71 | struct TermitModifier termit_modifiers[] = 72 | { 73 | {"Alt", GDK_MOD1_MASK}, 74 | {"Ctrl", GDK_CONTROL_MASK}, 75 | {"Shift", GDK_SHIFT_MASK}, 76 | {"Meta", GDK_META_MASK}, 77 | {"Super", GDK_SUPER_MASK}, 78 | {"Hyper", GDK_HYPER_MASK} 79 | }; 80 | static guint TermitModsSz = sizeof(termit_modifiers)/sizeof(struct TermitModifier); 81 | 82 | static gint get_modifier_state(const gchar* token) 83 | { 84 | size_t modifier_len; 85 | size_t step; 86 | 87 | if (!token) { 88 | return GDK_NOTHING; 89 | } 90 | guint i = 0; 91 | gint state = 0; 92 | while (strlen(token) > 0) { 93 | step = 0; 94 | for (; ilen; ++i) { 114 | struct KeyBinding* kb = &g_array_index(configs.key_bindings, struct KeyBinding, i); 115 | if (!strcmp(kb->name, name)) { 116 | return i; 117 | } 118 | } 119 | return -1; 120 | } 121 | 122 | struct TermitMouseEvent { 123 | const gchar* name; 124 | GdkEventType type; 125 | }; 126 | struct TermitMouseEvent termit_mouse_events[] = 127 | { 128 | {"DoubleClick", GDK_2BUTTON_PRESS} 129 | }; 130 | static guint TermitMouseEventsSz = sizeof(termit_mouse_events)/sizeof(struct TermitMouseEvent); 131 | 132 | gint get_mouse_event_type(const gchar* event_name) 133 | { 134 | if (!event_name) { 135 | return GDK_NOTHING; 136 | } 137 | guint i = 0; 138 | for (; ilen; ++i) { 150 | struct MouseBinding* mb = &g_array_index(configs.mouse_bindings, struct MouseBinding, i); 151 | if (type == mb->type) { 152 | return i; 153 | } 154 | } 155 | return -1; 156 | } 157 | 158 | void termit_keys_unbind(const gchar* keybinding) 159 | { 160 | gint kb_index = get_kb_index(keybinding); 161 | if (kb_index < 0) { 162 | TRACE("keybinding [%s] not found - skipping", keybinding); 163 | return; 164 | } 165 | struct KeyBinding* kb = &g_array_index(configs.key_bindings, struct KeyBinding, kb_index); 166 | termit_lua_unref(&kb->lua_callback); 167 | g_free(kb->name); 168 | g_array_remove_index(configs.key_bindings, kb_index); 169 | } 170 | 171 | int termit_parse_keys_str(const gchar* keybinding, struct KeyWithState* kws) 172 | { 173 | gchar *modifier = NULL, *key = NULL; 174 | // token[0] - modifier. Only Alt, Ctrl or Shift allowed. 175 | gchar** tokens = g_strsplit(keybinding, "-", 2); 176 | if (!tokens[0]) { 177 | ERROR("failed to parse: [%s]", keybinding); 178 | return -1; 179 | } 180 | if (!tokens[1]) { 181 | key = tokens[0]; 182 | } else { 183 | modifier = tokens[0]; 184 | key = tokens[1]; 185 | } 186 | gint tmp_state = 0; 187 | if (modifier) { 188 | tmp_state = get_modifier_state(modifier); 189 | if (tmp_state == GDK_NOTHING) { 190 | TRACE("Bad modifier: %s", keybinding); 191 | return -1; 192 | } 193 | } 194 | guint tmp_keyval = gdk_keyval_from_name(key); 195 | if (tmp_keyval == GDK_KEY_VoidSymbol) { 196 | TRACE("Bad keyval: %s", keybinding); 197 | return -1; 198 | } 199 | g_strfreev(tokens); 200 | kws->state = tmp_state; 201 | kws->keyval = gdk_keyval_to_lower(tmp_keyval); 202 | return 0; 203 | } 204 | 205 | void termit_keys_bind(const gchar* keybinding, int lua_callback) 206 | { 207 | struct KeyWithState kws = {}; 208 | if (termit_parse_keys_str(keybinding, &kws) < 0) { 209 | ERROR("failed to parse keybinding: %s", keybinding); 210 | return; 211 | } 212 | 213 | gint kb_index = get_kb_index(keybinding); 214 | if (kb_index < 0) { 215 | struct KeyBinding kb = {}; 216 | kb.name = g_strdup(keybinding); 217 | kb.kws = kws; 218 | kb.keycode = XKeysymToKeycode(disp, kb.kws.keyval); 219 | kb.lua_callback = lua_callback; 220 | g_array_append_val(configs.key_bindings, kb); 221 | } else { 222 | struct KeyBinding* kb = &g_array_index(configs.key_bindings, struct KeyBinding, kb_index); 223 | kb->kws = kws; 224 | kb->keycode = XKeysymToKeycode(disp, kb->kws.keyval); 225 | termit_lua_unref(&kb->lua_callback); 226 | kb->lua_callback = lua_callback; 227 | } 228 | } 229 | 230 | void termit_mouse_bind(const gchar* mouse_event, int lua_callback) 231 | { 232 | GdkEventType type = get_mouse_event_type(mouse_event); 233 | if (type == GDK_NOTHING) { 234 | TRACE("unknown event: %s", mouse_event); 235 | return; 236 | } 237 | gint mb_index = get_mb_index(type); 238 | if (mb_index < 0) { 239 | struct MouseBinding mb = {}; 240 | mb.type = type; 241 | mb.lua_callback = lua_callback; 242 | g_array_append_val(configs.mouse_bindings, mb); 243 | } else { 244 | struct MouseBinding* mb = &g_array_index(configs.mouse_bindings, struct MouseBinding, mb_index); 245 | mb->type = type; 246 | termit_lua_unref(&mb->lua_callback); 247 | mb->lua_callback = lua_callback; 248 | } 249 | } 250 | 251 | void termit_mouse_unbind(const gchar* mouse_event) 252 | { 253 | GdkEventType type = get_mouse_event_type(mouse_event); 254 | if (type == GDK_NOTHING) { 255 | TRACE("unknown event: %s", mouse_event); 256 | return; 257 | } 258 | gint mb_index = get_mb_index(type); 259 | if (mb_index < 0) { 260 | TRACE("mouse event [%d] not found - skipping", type); 261 | return; 262 | } 263 | struct MouseBinding* mb = &g_array_index(configs.mouse_bindings, struct MouseBinding, mb_index); 264 | termit_lua_unref(&mb->lua_callback); 265 | g_array_remove_index(configs.mouse_bindings, mb_index); 266 | } 267 | 268 | static gboolean termit_key_press_use_keycode(GdkEventKey *event) 269 | { 270 | guint i = 0; 271 | for (; ilen; ++i) { 272 | struct KeyBinding* kb = &g_array_index(configs.key_bindings, struct KeyBinding, i); 273 | if (kb && (event->state & kb->kws.state) == kb->kws.state) { 274 | if (event->hardware_keycode == kb->keycode) { 275 | termit_lua_dofunction(kb->lua_callback); 276 | return TRUE; 277 | } 278 | } 279 | } 280 | return FALSE; 281 | } 282 | 283 | static gboolean termit_key_press_use_keysym(GdkEventKey *event) 284 | { 285 | guint i = 0; 286 | for (; ilen; ++i) { 287 | struct KeyBinding* kb = &g_array_index(configs.key_bindings, struct KeyBinding, i); 288 | if (kb && (event->state & kb->kws.state) == kb->kws.state) { 289 | if (gdk_keyval_to_lower(event->keyval) == kb->kws.keyval) { 290 | termit_lua_dofunction(kb->lua_callback); 291 | return TRUE; 292 | } 293 | } 294 | } 295 | return FALSE; 296 | } 297 | 298 | gboolean termit_key_event(GdkEventKey* event) 299 | { 300 | switch(configs.kb_policy) { 301 | case TermitKbUseKeycode: 302 | return termit_key_press_use_keycode(event); 303 | break; 304 | case TermitKbUseKeysym: 305 | return termit_key_press_use_keysym(event); 306 | break; 307 | default: 308 | ERROR("unknown kb_policy: %d", configs.kb_policy); 309 | } 310 | return FALSE; 311 | } 312 | 313 | gboolean termit_mouse_event(GdkEventButton* event) 314 | { 315 | guint i = 0; 316 | for (; ilen; ++i) { 317 | struct MouseBinding* kb = &g_array_index(configs.mouse_bindings, struct MouseBinding, i); 318 | if (kb && (event->type & kb->type)) { 319 | termit_lua_dofunction(kb->lua_callback); 320 | } 321 | } 322 | return FALSE; 323 | } 324 | -------------------------------------------------------------------------------- /src/keybindings.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_KEYBINDINGS_H 18 | #define TERMIT_KEYBINDINGS_H 19 | 20 | #include 21 | #include 22 | 23 | struct KeyWithState 24 | { 25 | guint state; 26 | guint keyval; 27 | }; 28 | 29 | typedef void(*BindingCallback)(); 30 | struct KeyBinding 31 | { 32 | gchar* name; 33 | struct KeyWithState kws; 34 | KeySym keycode; 35 | int lua_callback; 36 | }; 37 | 38 | struct MouseBinding 39 | { 40 | GdkEventType type; 41 | int lua_callback; 42 | }; 43 | 44 | //void termit_load_keys(); 45 | int termit_parse_keys_str(const gchar* keybinding, struct KeyWithState* kws); 46 | void termit_keys_bind(const gchar* keys, int lua_callback); 47 | void termit_keys_unbind(const gchar* keys); 48 | void termit_mouse_bind(const gchar* mouse_event, int lua_callback); 49 | void termit_mouse_unbind(const gchar* mouse_event); 50 | void termit_keys_set_defaults(); 51 | gboolean termit_key_event(GdkEventKey* event); 52 | gboolean termit_mouse_event(GdkEventButton* event); 53 | #endif /* TERMIT_KEYBINDINGS_H */ 54 | -------------------------------------------------------------------------------- /src/lua_api.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_LUA_API_H 18 | #define TERMIT_LUA_API_H 19 | 20 | struct lua_State; 21 | 22 | void termit_lua_init_api(); 23 | void termit_lua_close(); 24 | void termit_lua_report_error(const char* file, int line, int status); 25 | void termit_lua_init(const gchar* initFile); 26 | void termit_lua_load_config(); 27 | void termit_lua_execute(const gchar* cmd); 28 | int termit_lua_dofunction(int f); 29 | int termit_lua_dofunction2(int f, const char* arg1); 30 | int termit_lua_domatch(int f, const gchar* matchedText); 31 | void termit_lua_unref(int* lua_callback); 32 | gchar* termit_lua_getTitleCallback(int f, const gchar* title); 33 | gchar* termit_lua_getStatusbarCallback(int f, guint page); 34 | int termit_get_lua_func(const char* name); 35 | 36 | typedef enum {TERMIT_LUA_TABLE_LOADER_OK, TERMIT_LUA_TABLE_LOADER_FAILED} TermitLuaTableLoaderResult; 37 | typedef void (*TermitLuaTableLoaderFunc)(const gchar*, struct lua_State*, int, void*); 38 | TermitLuaTableLoaderResult termit_lua_load_table(struct lua_State* ls, TermitLuaTableLoaderFunc func, 39 | const int tableIndex, void* data); 40 | int termit_lua_fill_tab(int tab_index, struct lua_State* ls); 41 | /** 42 | * Loaders 43 | * */ 44 | void termit_lua_options_loader(const gchar* name, struct lua_State* ls, int index, void* data); 45 | void termit_lua_keys_loader(const gchar* name, struct lua_State* ls, int index, void* data); 46 | void termit_lua_tab_loader(const gchar* name, struct lua_State* ls, int index, void* data); 47 | void termit_lua_load_colormap(struct lua_State* ls, int index, GdkRGBA** colors, glong* sz); 48 | void termit_config_get_string(gchar** opt, struct lua_State* ls, int index); 49 | void termit_config_get_double(double* opt, struct lua_State* ls, int index); 50 | void termit_config_getuint(guint* opt, struct lua_State* ls, int index); 51 | void termit_config_get_boolean(gboolean* opt, struct lua_State* ls, int index); 52 | void termit_config_get_function(int* opt, struct lua_State* ls, int index); 53 | void termit_config_get_color(GdkRGBA** opt, struct lua_State* ls, int index); 54 | void termit_config_get_erase_binding(VteEraseBinding* opt, struct lua_State* ls, int index); 55 | void termit_config_get_cursor_blink_mode(VteCursorBlinkMode* opt, struct lua_State* ls, int index); 56 | void termit_config_get_cursor_shape(VteCursorShape* opt, struct lua_State* ls, int index); 57 | 58 | #define TERMIT_TAB_ADD_NUMBER(name, value) {\ 59 | lua_pushstring(ls, name); \ 60 | lua_pushnumber(ls, value); \ 61 | lua_rawset(ls, -3); \ 62 | } 63 | #define TERMIT_TAB_ADD_STRING(name, value) {\ 64 | lua_pushstring(ls, name); \ 65 | lua_pushstring(ls, value); \ 66 | lua_rawset(ls, -3); \ 67 | } 68 | #define TERMIT_TAB_ADD_VOID(name, value) {\ 69 | lua_pushstring(ls, name); \ 70 | lua_pushlightuserdata(ls, value); \ 71 | lua_rawset(ls, -3); \ 72 | } 73 | #define TERMIT_TAB_ADD_BOOLEAN(name, value) {\ 74 | lua_pushstring(ls, name); \ 75 | lua_pushboolean(ls, value); \ 76 | lua_rawset(ls, -3); \ 77 | } 78 | #define TERMIT_TAB_ADD_CALLBACK(name, value) {\ 79 | lua_pushstring(ls, name); \ 80 | lua_rawgeti(ls, LUA_REGISTRYINDEX, value); \ 81 | lua_rawset(ls, -3); \ 82 | } 83 | #endif /* TERMIT_LUA_API_H */ 84 | -------------------------------------------------------------------------------- /src/lua_conf.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #include 18 | #include // XParseGeometry 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "termit.h" 26 | #include "termit_core_api.h" 27 | #include "configs.h" 28 | #include "keybindings.h" 29 | #include "lua_api.h" 30 | 31 | extern struct TermitData termit; 32 | extern struct Configs configs; 33 | 34 | lua_State* L = NULL; 35 | 36 | void termit_lua_close() 37 | { 38 | lua_close(L); 39 | } 40 | 41 | static void trace_menus(GArray* menus) 42 | { 43 | #ifdef DEBUG 44 | guint i = 0; 45 | for (; ilen; ++i) { 46 | struct UserMenu* um = &g_array_index(menus, struct UserMenu, i); 47 | TRACE("%s items %d", um->name, um->items->len); 48 | guint j = 0; 49 | for (; jitems->len; ++j) { 50 | struct UserMenuItem* umi = &g_array_index(um->items, struct UserMenuItem, j); 51 | TRACE(" %s: (%d) [%s]", umi->name, umi->lua_callback, umi->accel); 52 | } 53 | } 54 | #endif 55 | } 56 | 57 | void termit_config_get_string(gchar** opt, lua_State* ls, int index) 58 | { 59 | if (!lua_isnil(ls, index) && lua_isstring(ls, index)) { 60 | if (*opt) { 61 | g_free(*opt); 62 | } 63 | *opt = g_strdup(lua_tostring(ls, index)); 64 | } 65 | } 66 | 67 | void termit_config_get_double(double* opt, lua_State* ls, int index) 68 | { 69 | if (!lua_isnil(ls, index) && lua_isnumber(ls, index)) { 70 | *opt = lua_tonumber(ls, index); 71 | } 72 | } 73 | 74 | void termit_config_getuint(guint* opt, lua_State* ls, int index) 75 | { 76 | if (!lua_isnil(ls, index) && lua_isnumber(ls, index)) { 77 | *opt = lua_tointeger(ls, index); 78 | } 79 | } 80 | 81 | void termit_config_get_boolean(gboolean* opt, lua_State* ls, int index) 82 | { 83 | if (!lua_isnil(ls, index) && lua_isboolean(ls, index)) { 84 | *opt = lua_toboolean(ls, index); 85 | } 86 | } 87 | 88 | void termit_config_get_function(int* opt, lua_State* ls, int index) 89 | { 90 | if (!lua_isnil(ls, index) && lua_isfunction(ls, index)) { 91 | *opt = luaL_ref(ls, LUA_REGISTRYINDEX); // luaL_ref pops value so we restore stack size 92 | lua_pushnil(ls); 93 | } 94 | } 95 | 96 | void termit_config_get_color(GdkRGBA** opt, lua_State* ls, int index) 97 | { 98 | gchar* color_str = NULL; 99 | termit_config_get_string(&color_str, ls, index); 100 | if (color_str) { 101 | GdkRGBA color = {}; 102 | if (gdk_rgba_parse(&color, color_str) == TRUE) { 103 | *opt = gdk_rgba_copy(&color); 104 | TRACE("color_str=%s", color_str); 105 | } 106 | } 107 | g_free(color_str); 108 | } 109 | 110 | void termit_config_get_erase_binding(VteEraseBinding* opt, lua_State* ls, int index) 111 | { 112 | gchar* str = NULL; 113 | termit_config_get_string(&str, ls, index); 114 | *opt = termit_erase_binding_from_string(str); 115 | g_free(str); 116 | } 117 | 118 | void termit_config_get_cursor_blink_mode(VteCursorBlinkMode* opt, lua_State* ls, int index) 119 | { 120 | gchar* str = NULL; 121 | termit_config_get_string(&str, ls, index); 122 | *opt = termit_cursor_blink_mode_from_string(str); 123 | g_free(str); 124 | } 125 | 126 | void termit_config_get_cursor_shape(VteCursorShape* opt, lua_State* ls, int index) 127 | { 128 | gchar* str = NULL; 129 | termit_config_get_string(&str, ls, index); 130 | *opt = termit_cursor_shape_from_string(str); 131 | g_free(str); 132 | } 133 | 134 | static void matchesLoader(const gchar* pattern, struct lua_State* ls, int index, void* data) 135 | { 136 | TRACE("pattern=%s index=%d data=%p", pattern, index, data); 137 | if (!lua_isfunction(ls, index)) { 138 | ERROR("match [%s] without function: skipping", pattern); 139 | return; 140 | } 141 | GArray* matches = (GArray*)data; 142 | struct Match match = {}; 143 | GError* err = NULL; 144 | match.regex = vte_regex_new_for_match(pattern, -1, VTE_REGEX_FLAGS_DEFAULT, &err); 145 | if (err) { 146 | TRACE("failed to compile regex [%s]: skipping", pattern); 147 | return; 148 | } 149 | match.flags = 0; 150 | match.pattern = g_strdup(pattern); 151 | termit_config_get_function(&match.lua_callback, ls, index); 152 | g_array_append_val(matches, match); 153 | } 154 | 155 | struct ColormapHelper 156 | { 157 | GdkRGBA* colors; 158 | int idx; 159 | }; 160 | 161 | static void colormapLoader(const gchar* name, lua_State* ls, int index, void* data) 162 | { 163 | struct ColormapHelper* ch = (struct ColormapHelper*)data; 164 | if (!lua_isnil(ls, index) && lua_isstring(ls, index)) { 165 | const gchar* colorStr = lua_tostring(ls, index); 166 | if (!gdk_rgba_parse(&(ch->colors[ch->idx]), colorStr)) { 167 | ERROR("failed to parse color: %s %d - %s", name, ch->idx, colorStr); 168 | } 169 | } else { 170 | ERROR("invalid type in colormap: skipping"); 171 | } 172 | ++ch->idx; 173 | } 174 | 175 | static void tabsLoader(const gchar* name, lua_State* ls, int index, void* data) 176 | { 177 | if (lua_istable(ls, index)) { 178 | GArray* tabs = (GArray*)data; 179 | struct TabInfo ti = {}; 180 | if (termit_lua_load_table(ls, termit_lua_tab_loader, index, &ti) 181 | != TERMIT_LUA_TABLE_LOADER_OK) { 182 | ERROR("failed to load tab: %s %s", name, lua_tostring(ls, 3)); 183 | } else { 184 | g_array_append_val(tabs, ti); 185 | } 186 | } else { 187 | ERROR("unknown type instead if tab table: skipping"); 188 | lua_pop(ls, 1); 189 | } 190 | } 191 | 192 | void termit_lua_load_colormap(lua_State* ls, int index, GdkRGBA** colors, glong* sz) 193 | { 194 | if (lua_isnil(ls, index) || !lua_istable(ls, index)) { 195 | ERROR("invalid colormap type"); 196 | return; 197 | } 198 | const int size = lua_rawlen(ls, index); 199 | if ((size != 8) && (size != 16) && (size != 24)) { 200 | ERROR("bad colormap length: %d", size); 201 | return; 202 | } 203 | struct ColormapHelper ch = {}; 204 | ch.colors = g_malloc0(size * sizeof(GdkRGBA)); 205 | if (termit_lua_load_table(ls, colormapLoader, index, &ch) 206 | == TERMIT_LUA_TABLE_LOADER_OK) { 207 | if (*colors) { 208 | g_free(*colors); 209 | } 210 | *colors = ch.colors; 211 | *sz = size; 212 | } else { 213 | ERROR("failed to load colormap"); 214 | return; 215 | } 216 | TRACE("colormap loaded: size=%ld", *sz); 217 | } 218 | 219 | static void termit_config_get_tabbar_position(GtkPositionType* pos, lua_State* ls, int index) 220 | { 221 | if (!lua_isnil(ls, index) && lua_isstring(ls, index)) { 222 | const char* str = lua_tostring(ls, index); 223 | if (strcmp(str, "Top") == 0) { 224 | *pos = GTK_POS_TOP; 225 | } else if (strcmp(str, "Bottom") == 0) { 226 | *pos = GTK_POS_BOTTOM; 227 | } else if (strcmp(str, "Left") == 0) { 228 | *pos = GTK_POS_LEFT; 229 | } else if (strcmp(str, "Right") == 0) { 230 | *pos = GTK_POS_RIGHT; 231 | } else { 232 | ERROR("unknown pos: [%s]", str); 233 | } 234 | } 235 | } 236 | 237 | void termit_lua_options_loader(const gchar* name, lua_State* ls, int index, void* data) 238 | { 239 | struct Configs* p_cfg = (struct Configs*)data; 240 | if (!strcmp(name, "tabName")) { 241 | termit_config_get_string(&(p_cfg->default_tab_name), ls, index); 242 | } else if (!strcmp(name, "windowTitle")) { 243 | termit_config_get_string(&(p_cfg->default_window_title), ls, index); 244 | } else if (!strcmp(name, "encoding")) { 245 | termit_config_get_string(&(p_cfg->default_encoding), ls, index); 246 | } else if (!strcmp(name, "wordCharExceptions")) { 247 | termit_config_get_string(&(p_cfg->default_word_char_exceptions), ls, index); 248 | } else if (!strcmp(name, "font")) { 249 | termit_config_get_string(&(p_cfg->style.font_name), ls, index); 250 | } else if (!strcmp(name, "foregroundColor")) { 251 | termit_config_get_color(&p_cfg->style.foreground_color, ls, index); 252 | } else if (!strcmp(name, "backgroundColor")) { 253 | termit_config_get_color(&p_cfg->style.background_color, ls, index); 254 | } else if (!strcmp(name, "showScrollbar")) { 255 | termit_config_get_boolean(&(p_cfg->show_scrollbar), ls, index); 256 | } else if (!strcmp(name, "fillTabbar")) { 257 | termit_config_get_boolean(&(p_cfg->fill_tabbar), ls, index); 258 | } else if (!strcmp(name, "hideSingleTab")) { 259 | termit_config_get_boolean(&(p_cfg->hide_single_tab), ls, index); 260 | } else if (!strcmp(name, "hideMenubar")) { 261 | termit_config_get_boolean(&(p_cfg->hide_menubar), ls, index); 262 | } else if (!strcmp(name, "hideTabbar")) { 263 | termit_config_get_boolean(&(p_cfg->hide_tabbar), ls, index); 264 | } else if (!strcmp(name, "showBorder")) { 265 | termit_config_get_boolean(&(p_cfg->show_border), ls, index); 266 | } else if (!strcmp(name, "startMaximized")) { 267 | termit_config_get_boolean(&(p_cfg->start_maximized), ls, index); 268 | } else if (!strcmp(name, "hideTitlebarWhenMaximized")) { 269 | termit_config_get_boolean(&(p_cfg->hide_titlebar_when_maximized), ls, index); 270 | } else if (!strcmp(name, "scrollbackLines")) { 271 | termit_config_getuint(&(p_cfg->scrollback_lines), ls, index); 272 | } else if (!strcmp(name, "allowChangingTitle")) { 273 | termit_config_get_boolean(&(p_cfg->allow_changing_title), ls, index); 274 | } else if (!strcmp(name, "audibleBell")) { 275 | termit_config_get_boolean(&(p_cfg->audible_bell), ls, index); 276 | } else if (!strcmp(name, "scrollOnOutput")) { 277 | termit_config_get_boolean(&(p_cfg->scroll_on_output), ls, index); 278 | } else if (!strcmp(name, "scrollOnKeystroke")) { 279 | termit_config_get_boolean(&(p_cfg->scroll_on_keystroke), ls, index); 280 | } else if (!strcmp(name, "urgencyOnBell")) { 281 | termit_config_get_boolean(&(p_cfg->urgency_on_bell), ls, index); 282 | } else if (!strcmp(name, "getWindowTitle")) { 283 | termit_config_get_function(&(p_cfg->get_window_title_callback), ls, index); 284 | } else if (!strcmp(name, "tabPos")) { 285 | termit_config_get_tabbar_position(&(p_cfg->tab_pos), ls, index); 286 | } else if (!strcmp(name, "tabCloseButton")) { 287 | termit_config_get_boolean(&(p_cfg->tab_close_button), ls, index); 288 | } else if (!strcmp(name, "getTabTitle")) { 289 | termit_config_get_function(&(p_cfg->get_tab_title_callback), ls, index); 290 | } else if (!strcmp(name, "setStatusbar")) { 291 | termit_config_get_function(&(p_cfg->get_statusbar_callback), ls, index); 292 | } else if (!strcmp(name, "backspaceBinding")) { 293 | termit_config_get_erase_binding(&(p_cfg->default_bksp), ls, index); 294 | } else if (!strcmp(name, "deleteBinding")) { 295 | termit_config_get_erase_binding(&(p_cfg->default_delete), ls, index); 296 | } else if (!strcmp(name, "cursorBlinkMode")) { 297 | termit_config_get_cursor_blink_mode(&(p_cfg->default_blink), ls, index); 298 | } else if (!strcmp(name, "cursorShape")) { 299 | termit_config_get_cursor_shape(&(p_cfg->default_shape), ls, index); 300 | } else if (!strcmp(name, "colormap")) { 301 | termit_lua_load_colormap(ls, index, &configs.style.colors, &configs.style.colors_size); 302 | } else if (!strcmp(name, "matches")) { 303 | if (termit_lua_load_table(ls, matchesLoader, index, configs.matches) 304 | != TERMIT_LUA_TABLE_LOADER_OK) { 305 | ERROR("failed to load matches"); 306 | } 307 | } else if (!strcmp(name, "geometry")) { 308 | gchar* geometry_str = NULL; 309 | termit_config_get_string(&geometry_str, ls, index); 310 | if (geometry_str) { 311 | unsigned int cols = 0, rows = 0; 312 | int tmp1 = 0, tmp2 = 0; 313 | XParseGeometry(geometry_str, &tmp1, &tmp2, &cols, &rows); 314 | if ((cols != 0) && (rows != 0)) { 315 | p_cfg->cols = cols; 316 | p_cfg->rows = rows; 317 | } 318 | } 319 | g_free(geometry_str); 320 | } else if (!strcmp(name, "tabs")) { 321 | if (lua_istable(ls, index)) { 322 | if (!configs.default_tabs) { 323 | configs.default_tabs = g_array_new(FALSE, TRUE, sizeof(struct TabInfo)); 324 | } 325 | TRACE("tabs at index: %d tabs.size=%d", index, configs.default_tabs->len); 326 | if (termit_lua_load_table(ls, tabsLoader, index, configs.default_tabs) 327 | != TERMIT_LUA_TABLE_LOADER_OK) { 328 | ERROR("openTab failed"); 329 | } 330 | } else { 331 | ERROR("expecting table"); 332 | } 333 | } 334 | } 335 | 336 | static void termit_lua_add_package_path(const gchar* path) 337 | { 338 | gchar* luaCmd = g_strdup_printf("package.path = package.path .. \";%s/?.lua\"", path); 339 | int s = luaL_dostring(L, luaCmd); 340 | termit_lua_report_error(__FILE__, __LINE__, s); 341 | g_free(luaCmd); 342 | } 343 | 344 | static gchar** termit_system_path() 345 | { 346 | const gchar *configSystem = g_getenv("XDG_CONFIG_DIRS"); 347 | gchar* xdgConfigDirs = NULL; 348 | if (configSystem) { 349 | xdgConfigDirs = g_strdup_printf("%s:/etc/xdg", configSystem); 350 | } else { 351 | xdgConfigDirs = g_strdup("/etc/xdg"); 352 | } 353 | gchar** systemPaths = g_strsplit(xdgConfigDirs, ":", 0); 354 | g_free(xdgConfigDirs); 355 | return systemPaths; 356 | } 357 | 358 | static gchar* termit_user_path() 359 | { 360 | const gchar *configHome = g_getenv("XDG_CONFIG_HOME"); 361 | if (configHome) { 362 | return g_strdup(configHome); 363 | } else { 364 | return g_strdup_printf("%s/.config", g_getenv("HOME")); 365 | } 366 | } 367 | 368 | static void load_init(const gchar* initFile) 369 | { 370 | const gchar *configFile = "rc.lua"; 371 | gchar** systemPaths = termit_system_path(); 372 | guint i = 0; 373 | gchar* systemPath = systemPaths[i]; 374 | while (systemPath) { 375 | if (g_file_test(systemPath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) == TRUE) { 376 | termit_lua_add_package_path(systemPath); 377 | } 378 | systemPath = systemPaths[++i]; 379 | } 380 | gchar* userPath = termit_user_path(); 381 | termit_lua_add_package_path(userPath); 382 | 383 | gchar* fullPath = NULL; 384 | if (initFile) { 385 | fullPath = g_strdup(initFile); 386 | } else { 387 | fullPath = g_strdup_printf("%s/termit/%s", userPath, configFile); 388 | if (g_file_test(fullPath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR) == FALSE) { 389 | TRACE("%s not found", fullPath); 390 | g_free(fullPath); 391 | 392 | i = 0; 393 | gchar* systemPath = systemPaths[i]; 394 | while (systemPath) { 395 | fullPath = g_strdup_printf("%s/termit/%s", systemPath, configFile); 396 | if (g_file_test(fullPath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR) == FALSE) { 397 | TRACE("%s not found", fullPath); 398 | g_free(fullPath); 399 | fullPath = NULL; 400 | } else { 401 | break; 402 | } 403 | systemPath = systemPaths[++i]; 404 | } 405 | } 406 | } 407 | g_strfreev(systemPaths); 408 | g_free(userPath); 409 | if (fullPath) { 410 | TRACE("using config: %s", fullPath); 411 | int s = luaL_loadfile(L, fullPath); 412 | termit_lua_report_error(__FILE__, __LINE__, s); 413 | g_free(fullPath); 414 | 415 | s = lua_pcall(L, 0, LUA_MULTRET, 0); 416 | termit_lua_report_error(__FILE__, __LINE__, s); 417 | } else { 418 | ERROR("config file %s not found", configFile); 419 | } 420 | } 421 | 422 | int termit_lua_fill_tab(int tab_index, lua_State* ls) 423 | { 424 | TERMIT_GET_TAB_BY_INDEX(pTab, tab_index, return 0); 425 | lua_newtable(ls); 426 | TERMIT_TAB_ADD_STRING("title", pTab->title); 427 | TERMIT_TAB_ADD_STRING("command", pTab->argv[0]); 428 | TERMIT_TAB_ADD_STRING("argv", ""); 429 | // FIXME: add argv 430 | TERMIT_TAB_ADD_STRING("encoding", pTab->encoding); 431 | gchar* working_dir = termit_get_pid_dir(pTab->pid); 432 | TERMIT_TAB_ADD_STRING("workingDir", working_dir); 433 | g_free(working_dir); 434 | TERMIT_TAB_ADD_NUMBER("pid", pTab->pid); 435 | TERMIT_TAB_ADD_STRING("font", pTab->style.font_name); 436 | TERMIT_TAB_ADD_NUMBER("fontSize", pango_font_description_get_size(pTab->style.font)/PANGO_SCALE); 437 | TERMIT_TAB_ADD_STRING("backspaceBinding", termit_erase_binding_to_string(pTab->bksp_binding)); 438 | TERMIT_TAB_ADD_STRING("deleteBinding", termit_erase_binding_to_string(pTab->delete_binding)); 439 | TERMIT_TAB_ADD_STRING("cursorBlinkMode", termit_cursor_blink_mode_to_string(pTab->cursor_blink_mode)); 440 | TERMIT_TAB_ADD_STRING("cursorShape", termit_cursor_shape_to_string(pTab->cursor_shape)); 441 | return 1; 442 | } 443 | 444 | static int termit_lua_tabs_index(lua_State* ls) 445 | { 446 | if (lua_isnumber(ls, 1)) { 447 | TRACE_MSG("index is not number: skipping"); 448 | return 0; 449 | } 450 | int tab_index = lua_tointeger(ls, -1); 451 | TRACE("tab_index:%d", tab_index); 452 | return termit_lua_fill_tab(tab_index - 1, ls); 453 | } 454 | 455 | static int termit_lua_tabs_newindex(lua_State* ls) 456 | { 457 | ERROR("'tabs' is read-only variable"); 458 | return 0; 459 | } 460 | 461 | static void termit_lua_init_tabs() 462 | { 463 | lua_newtable(L); 464 | luaL_newmetatable(L, "tabs_meta"); 465 | lua_pushcfunction(L, termit_lua_tabs_index); 466 | lua_setfield(L, -2, "__index"); 467 | lua_pushcfunction(L, termit_lua_tabs_newindex); 468 | lua_setfield(L, -2, "__newindex"); 469 | lua_setmetatable(L, -2); 470 | lua_setglobal(L, "tabs"); 471 | } 472 | 473 | static const gchar* termit_init_file = NULL; 474 | 475 | void termit_lua_load_config() 476 | { 477 | load_init(termit_init_file); 478 | termit_config_trace(); 479 | 480 | trace_menus(configs.user_menus); 481 | trace_menus(configs.user_popup_menus); 482 | } 483 | 484 | void termit_lua_init(const gchar* initFile) 485 | { 486 | L = luaL_newstate(); 487 | luaL_openlibs(L); 488 | 489 | if (!termit_init_file) { 490 | termit_init_file = g_strdup(initFile); 491 | } 492 | termit_lua_init_tabs(); 493 | termit_lua_init_api(); 494 | termit_keys_set_defaults(); 495 | termit_lua_load_config(); 496 | } 497 | -------------------------------------------------------------------------------- /src/sessions.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "termit.h" 32 | #include "termit_core_api.h" 33 | #include "configs.h" 34 | #include "callbacks.h" 35 | #include "lua_api.h" 36 | #include "sessions.h" 37 | 38 | extern lua_State* L; 39 | 40 | // from Openbox 41 | static gboolean parse_mkdir(const gchar *path, gint mode) 42 | { 43 | gboolean ret = TRUE; 44 | g_return_val_if_fail(path != NULL, FALSE); 45 | g_return_val_if_fail(path[0] != '\0', FALSE); 46 | if (!g_file_test(path, G_FILE_TEST_IS_DIR)) { 47 | if (mkdir(path, mode) == -1) { 48 | ret = FALSE; 49 | } 50 | } 51 | return ret; 52 | } 53 | 54 | // from Openbox 55 | static gboolean parse_mkdir_path(const gchar *path, gint mode) 56 | { 57 | gboolean ret = TRUE; 58 | g_return_val_if_fail(path != NULL, FALSE); 59 | g_return_val_if_fail(path[0] == '/', FALSE); 60 | if (!g_file_test(path, G_FILE_TEST_IS_DIR)) { 61 | gchar *c, *e; 62 | c = g_strdup(path); 63 | e = c; 64 | while ((e = strchr(e + 1, '/'))) { 65 | *e = '\0'; 66 | if (!(ret = parse_mkdir(c, mode))) { 67 | goto parse_mkdir_path_end; 68 | } 69 | *e = '/'; 70 | } 71 | ret = parse_mkdir(c, mode); 72 | 73 | parse_mkdir_path_end: 74 | g_free(c); 75 | } 76 | return ret; 77 | } 78 | 79 | void termit_init_sessions() 80 | { 81 | gchar *fullPath; 82 | const gchar *dataHome = g_getenv("XDG_DATA_HOME"); 83 | if (dataHome) { 84 | fullPath = g_strdup_printf("%s/termit", dataHome); 85 | } else { 86 | fullPath = g_strdup_printf("%s/.local/share/termit", g_getenv("HOME")); 87 | } 88 | TRACE("%s %s", __FUNCTION__, fullPath); 89 | if (!parse_mkdir_path(fullPath, 0700)) { 90 | g_message(_("Unable to create directory '%s': %s"), fullPath, g_strerror(errno)); 91 | } 92 | g_free(fullPath); 93 | } 94 | 95 | void termit_load_session(const gchar* sessionFile) 96 | { 97 | TRACE("loading sesions from %s", sessionFile); 98 | int s = luaL_dofile(L, sessionFile); 99 | termit_lua_report_error(__FILE__, __LINE__, s); 100 | } 101 | 102 | /** 103 | * saves session as lua-script 104 | * */ 105 | void termit_save_session(const gchar* sessionFile) 106 | { 107 | TRACE("saving session to file %s", sessionFile); 108 | FILE* fd = g_fopen(sessionFile, "w"); 109 | if ((intptr_t)fd == -1) { 110 | TRACE("failed savimg to %s", sessionFile); 111 | return; 112 | } 113 | 114 | guint pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(termit.notebook)); 115 | 116 | guint i = 0; 117 | for (; i < pages; ++i) { 118 | TERMIT_GET_TAB_BY_INDEX(pTab, i, continue); 119 | gchar* working_dir = termit_get_pid_dir(pTab->pid); 120 | gchar* groupName = g_strdup_printf("tab%d", i); 121 | g_fprintf(fd, "%s = {}\n", groupName); 122 | GtkWidget* label = gtk_box_get_center_widget(GTK_BOX(pTab->tab_name)); 123 | g_fprintf(fd, "%s.title = \"%s\"\n", groupName, gtk_label_get_text(GTK_LABEL(label))); 124 | g_fprintf(fd, "%s.workingDir = \"%s\"\n", groupName, working_dir); 125 | g_fprintf(fd, "%s.command = \"%s\"\n", groupName, pTab->argv[0]); 126 | // FIXME compund commands would not be saved 127 | g_fprintf(fd, "%s.argv = {}\n", groupName); 128 | g_fprintf(fd, "%s.encoding = \"%s\"\n", groupName, pTab->encoding); 129 | GValue val = {}; 130 | g_value_init(&val, g_type_from_name("VteEraseBinding")); 131 | g_object_get_property(G_OBJECT(pTab->vte), "backspace-binding", &val); 132 | VteEraseBinding eb = g_value_get_enum(&val); 133 | if (eb != VTE_ERASE_AUTO) { 134 | g_fprintf(fd, "%s.backspaceBinding = \"%s\"\n", groupName, termit_erase_binding_to_string(eb)); 135 | } 136 | g_value_unset(&val); 137 | g_value_init(&val, g_type_from_name("VteEraseBinding")); 138 | g_object_get_property(G_OBJECT(pTab->vte), "delete-binding", &val); 139 | eb = g_value_get_enum(&val); 140 | if (eb != VTE_ERASE_AUTO) { 141 | g_fprintf(fd, "%s.deleteBinding = \"%s\"\n", groupName, termit_erase_binding_to_string(eb)); 142 | } 143 | g_value_unset(&val); 144 | if (pTab->cursor_blink_mode != VTE_CURSOR_BLINK_SYSTEM) { 145 | g_fprintf(fd, "%s.cursorBlinkMode = \"%s\"\n", groupName, termit_cursor_blink_mode_to_string(pTab->cursor_blink_mode)); 146 | } 147 | if (pTab->cursor_shape != VTE_CURSOR_SHAPE_BLOCK) { 148 | g_fprintf(fd, "%s.cursorShape = \"%s\"\n", groupName, termit_cursor_shape_to_string(pTab->cursor_shape)); 149 | } 150 | g_fprintf(fd, "openTab(%s)\n\n", groupName); 151 | g_free(groupName); 152 | g_free(working_dir); 153 | } 154 | // g_fprintf(fd, data); 155 | fclose(fd); 156 | } 157 | -------------------------------------------------------------------------------- /src/sessions.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_SESSIONS_H 18 | #define TERMIT_SESSIONS_H 19 | 20 | void termit_init_sessions(); 21 | void termit_load_session(const gchar* sessionFile); 22 | void termit_save_session(const gchar* sessionFile); 23 | 24 | #endif /* TERMIT_SESSIONS_H */ 25 | -------------------------------------------------------------------------------- /src/termit.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_H 18 | #define TERMIT_H 19 | 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #define _(String) gettext(String) 29 | 30 | #include "termit_style.h" 31 | 32 | struct TermitData 33 | { 34 | GtkWidget *main_window; 35 | GtkWidget *notebook; 36 | GtkWidget *statusbar; 37 | GtkWidget *b_toggle_search; 38 | GtkWidget *b_find_next; 39 | GtkWidget *b_find_prev; 40 | GtkWidget *search_entry; 41 | GtkWidget *cb_bookmarks; 42 | GtkWidget *menu; 43 | GtkWidget *mi_show_scrollbar; 44 | GtkWidget *hbox; 45 | GtkWidget *menu_bar; 46 | gint tab_max_number; 47 | }; 48 | extern struct TermitData termit; 49 | 50 | struct TermitTab 51 | { 52 | GtkWidget *tab_name; 53 | GtkWidget *hbox; 54 | GtkWidget *vte; 55 | GtkWidget *scrollbar; 56 | gboolean scrollbar_is_shown; 57 | gboolean custom_tab_name; 58 | gboolean audible_bell; 59 | VteEraseBinding bksp_binding; 60 | VteEraseBinding delete_binding; 61 | VteCursorBlinkMode cursor_blink_mode; 62 | VteCursorShape cursor_shape; 63 | gchar *encoding; 64 | gchar **argv; 65 | gchar *title; 66 | GArray* matches; 67 | gchar* search_regex; 68 | struct TermitStyle style; 69 | GPid pid; 70 | gulong onChildExitedHandlerId; 71 | }; 72 | 73 | struct TabInfo 74 | { 75 | gchar* name; 76 | gchar** argv; 77 | gchar* working_dir; 78 | gchar* encoding; 79 | VteEraseBinding bksp_binding; 80 | VteEraseBinding delete_binding; 81 | VteCursorBlinkMode cursor_blink_mode; 82 | VteCursorShape cursor_shape; 83 | }; 84 | 85 | struct TermitTab* termit_get_tab_by_index(guint); 86 | #define TERMIT_GET_TAB_BY_INDEX(pTab, ind, action) \ 87 | struct TermitTab* pTab = termit_get_tab_by_index(ind); \ 88 | if (!pTab) \ 89 | { g_fprintf(stderr, "%s:%d error: %s is null\n", __FILE__, __LINE__, #pTab); action; } 90 | struct TermitTab* termit_get_tab_by_vte(VteTerminal*, gint*); 91 | 92 | #ifdef DEBUG 93 | #define ERROR(format, ...) g_fprintf(stderr, "ERROR: %s:%d " format "\n", __FILE__, __LINE__, ## __VA_ARGS__) 94 | #define STDFMT "%s:%d " 95 | #define STD __FILE__, __LINE__ 96 | #define TRACE(format, ...) g_fprintf(stderr, STDFMT format, STD, ## __VA_ARGS__); g_fprintf(stderr, "\n") 97 | #define TRACE_MSG(x) g_fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, x) 98 | #define TRACE_FUNC g_fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__) 99 | #else 100 | #define ERROR(format, ...) g_fprintf(stderr, "%s:%d " format "\n", __FILE__, __LINE__, ## __VA_ARGS__) 101 | #define TRACE(format, ...) 102 | #define TRACE_MSG(x) 103 | #define TRACE_FUNC 104 | #endif 105 | 106 | #endif /* TERMIT_H */ 107 | -------------------------------------------------------------------------------- /src/termit_core_api.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_CORE_API_H 18 | #define TERMIT_CORE_API_H 19 | 20 | #include "termit.h" 21 | #include "configs.h" 22 | 23 | void termit_reconfigure(); 24 | void termit_after_show_all(); 25 | 26 | void termit_append_tab(); 27 | void termit_append_tab_with_command(gchar** argv); 28 | void termit_append_tab_with_details(const struct TabInfo*); 29 | 30 | void termit_activate_tab(gint tab_index); 31 | void termit_prev_tab(); 32 | void termit_next_tab(); 33 | void termit_paste(); 34 | void termit_copy(); 35 | gchar* termit_get_selection(); 36 | void termit_search_find_next(); 37 | void termit_search_find_prev(); 38 | void termit_for_each_row(int lua_callback); 39 | void termit_for_each_visible_row(int lua_callback); 40 | void termit_del_tab_n(gint page); 41 | void termit_close_tab(); 42 | void termit_toggle_menubar(); 43 | void termit_toggle_tabbar(); 44 | void termit_toggle_search(); 45 | void termit_set_window_title(const gchar* title); 46 | void termit_set_statusbar_message(guint page); 47 | void termit_set_encoding(const gchar* encoding); 48 | void termit_quit(); 49 | 50 | void termit_tab_feed(struct TermitTab* pTab, const gchar* data); 51 | void termit_tab_feed_child(struct TermitTab* pTab, const gchar* data); 52 | void termit_tab_set_font(struct TermitTab* pTab, const gchar* font_name); 53 | void termit_tab_set_font_by_index(gint tab_index, const gchar* font_name); 54 | void termit_tab_apply_colors(struct TermitTab* pTab); 55 | void termit_tab_set_color_foreground(struct TermitTab* pTab, const GdkRGBA* p_color); 56 | void termit_tab_set_color_background(struct TermitTab* pTab, const GdkRGBA* p_color); 57 | void termit_tab_set_color_foreground_by_index(gint tab_index, const GdkRGBA*); 58 | void termit_tab_set_color_background_by_index(gint tab_index, const GdkRGBA*); 59 | void termit_tab_set_title(struct TermitTab* pTab, const gchar* title); 60 | void termit_tab_set_audible_bell(struct TermitTab* pTab, gboolean audible_bell); 61 | void termit_tab_set_pos(struct TermitTab* pTab, int newPos); 62 | 63 | int termit_get_current_tab_index(); 64 | gchar* termit_get_pid_dir(pid_t pid); 65 | 66 | /** 67 | * function to switch key processing policy 68 | * keycodes - kb layout independent 69 | * keysyms - kb layout dependent 70 | * */ 71 | void termit_set_kb_policy(enum TermitKbPolicy kbp); 72 | void termit_set_show_scrollbar_signal(GtkWidget* menuItem, gpointer pHanderId); 73 | 74 | #endif /* TERMIT_CORE_API_H */ 75 | -------------------------------------------------------------------------------- /src/termit_preferences.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "termit.h" 22 | #include "termit_style.h" 23 | #include "termit_core_api.h" 24 | 25 | static gboolean dlg_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 26 | { 27 | switch (event->keyval) { 28 | case GDK_KEY_Return: 29 | g_signal_emit_by_name(widget, "response", GTK_RESPONSE_ACCEPT, NULL); 30 | break; 31 | case GDK_KEY_Escape: 32 | g_signal_emit_by_name(widget, "response", GTK_RESPONSE_REJECT, NULL); 33 | break; 34 | default: 35 | return FALSE; 36 | } 37 | return TRUE; 38 | } 39 | 40 | static void dlg_set_tab_color__(GtkColorButton *widget, gpointer user_data, void (*callback)(struct TermitTab*, const GdkRGBA*)) 41 | { 42 | if (!user_data) { 43 | ERROR("user_data is NULL"); 44 | return; 45 | } 46 | struct TermitTab* pTab = (struct TermitTab*)user_data; 47 | GdkRGBA color = {}; 48 | gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &color); 49 | callback(pTab, &color); 50 | } 51 | static void dlg_set_foreground(GtkColorButton *widget, gpointer user_data) 52 | { 53 | return dlg_set_tab_color__(widget, user_data, termit_tab_set_color_foreground); 54 | } 55 | static void dlg_set_background(GtkColorButton *widget, gpointer user_data) 56 | { 57 | return dlg_set_tab_color__(widget, user_data, termit_tab_set_color_background); 58 | } 59 | static void dlg_set_font(GtkFontChooser *widget, gpointer user_data) 60 | { 61 | if (!user_data) { 62 | ERROR("user_data is NULL"); 63 | return; 64 | } 65 | struct TermitTab* pTab = (struct TermitTab*)user_data; 66 | termit_tab_set_font(pTab, gtk_font_chooser_get_font(widget)); 67 | } 68 | static gboolean dlg_set_audible_bell(GtkToggleButton *btn, gpointer user_data) 69 | { 70 | if (!user_data) { 71 | ERROR("user_data is NULL"); 72 | return FALSE; 73 | } 74 | struct TermitTab* pTab = (struct TermitTab*)user_data; 75 | gboolean value = gtk_toggle_button_get_active(btn); 76 | termit_tab_set_audible_bell(pTab, value); 77 | return FALSE; 78 | } 79 | static gboolean dlg_set_apply_to_all_tabs(GtkToggleButton *btn, gpointer user_data) 80 | { 81 | if (!user_data) { 82 | ERROR("user_data is NULL"); 83 | return FALSE; 84 | } 85 | gboolean* flag = (gboolean*)user_data; 86 | *flag = gtk_toggle_button_get_active(btn); 87 | return FALSE; 88 | } 89 | 90 | struct TermitDlgHelper 91 | { 92 | struct TermitTab* pTab; 93 | gchar* tab_title; 94 | gboolean handmade_tab_title; 95 | struct TermitStyle style; 96 | gboolean au_bell; 97 | // widgets with values 98 | GtkWidget* dialog; 99 | GtkWidget* entry_title; 100 | GtkWidget* btn_font; 101 | GtkWidget* btn_foreground; 102 | GtkWidget* btn_background; 103 | GtkWidget* btn_audible_bell; 104 | GtkWidget* btn_apply_to_all_tabs; 105 | }; 106 | 107 | static struct TermitDlgHelper* termit_dlg_helper_new(struct TermitTab* pTab) 108 | { 109 | struct TermitDlgHelper* hlp = g_malloc0(sizeof(struct TermitDlgHelper)); 110 | hlp->pTab = pTab; 111 | if (pTab->title) { 112 | hlp->handmade_tab_title = TRUE; 113 | hlp->tab_title = g_strdup(pTab->title); 114 | } else { 115 | GtkWidget* label = gtk_box_get_center_widget(GTK_BOX(pTab->tab_name)); 116 | hlp->tab_title = g_strdup(gtk_label_get_text(GTK_LABEL(label))); 117 | } 118 | termit_style_copy(&hlp->style, &pTab->style); 119 | hlp->au_bell = pTab->audible_bell; 120 | return hlp; 121 | } 122 | 123 | static void termit_dlg_helper_free(struct TermitDlgHelper* hlp) 124 | { 125 | g_free(hlp->tab_title); 126 | termit_style_free(&hlp->style); 127 | g_free(hlp); 128 | } 129 | 130 | static void dlg_set_tab_default_values(struct TermitTab* pTab, struct TermitDlgHelper* hlp) 131 | { 132 | if (hlp->tab_title) { 133 | termit_tab_set_title(pTab, hlp->tab_title); 134 | } 135 | termit_style_free(&pTab->style); 136 | termit_style_copy(&pTab->style, &hlp->style); 137 | termit_tab_apply_colors(pTab); 138 | termit_tab_set_font(pTab, hlp->style.font_name); 139 | termit_tab_set_audible_bell(pTab, hlp->au_bell); 140 | } 141 | 142 | static void dlg_set_default_values(struct TermitDlgHelper* hlp) 143 | { 144 | gtk_entry_set_text(GTK_ENTRY(hlp->entry_title), hlp->tab_title); 145 | gtk_font_chooser_set_font(GTK_FONT_CHOOSER(hlp->btn_font), hlp->style.font_name); 146 | if (hlp->style.foreground_color) { 147 | gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(hlp->btn_foreground), hlp->style.foreground_color); 148 | } 149 | if (hlp->style.background_color) { 150 | gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(hlp->btn_background), hlp->style.background_color); 151 | } 152 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hlp->btn_audible_bell), hlp->au_bell); 153 | } 154 | 155 | static void dlg_restore_defaults(GtkButton *button, gpointer user_data) 156 | { 157 | struct TermitDlgHelper* hlp = (struct TermitDlgHelper*)user_data; 158 | dlg_set_default_values(hlp); 159 | dlg_set_tab_default_values(hlp->pTab, hlp); 160 | } 161 | 162 | void termit_preferences_dialog(struct TermitTab *pTab) 163 | { 164 | // store font_name, foreground, background 165 | struct TermitDlgHelper* hlp = termit_dlg_helper_new(pTab); 166 | 167 | GtkWidget* dialog = gtk_dialog_new_with_buttons(_("Preferences"), 168 | GTK_WINDOW(termit.main_window), 169 | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, 170 | "_Cancel", GTK_RESPONSE_REJECT, 171 | "_Apply", GTK_RESPONSE_ACCEPT, 172 | NULL); 173 | g_signal_connect(G_OBJECT(dialog), "key-press-event", G_CALLBACK(dlg_key_press), dialog); 174 | GtkWidget* grid = gtk_grid_new(); 175 | 176 | #define TERMIT_PREFERENCE_ROW(pref_name, widget) \ 177 | gtk_grid_attach(GTK_GRID(grid), gtk_label_new(pref_name), 0, row, 1, 1); \ 178 | gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1); \ 179 | hlp->widget = widget; \ 180 | row++; 181 | 182 | gboolean apply_to_all_tabs_flag = FALSE; 183 | GtkWidget* entry_title = gtk_entry_new(); 184 | guint row = 0; 185 | { // tab title 186 | gtk_entry_set_text(GTK_ENTRY(entry_title), hlp->tab_title); 187 | TERMIT_PREFERENCE_ROW(_("Title"), entry_title); 188 | } 189 | 190 | // font selection 191 | GtkWidget* btn_font = gtk_font_button_new_with_font(pTab->style.font_name); 192 | g_signal_connect(btn_font, "font-set", G_CALLBACK(dlg_set_font), pTab); 193 | TERMIT_PREFERENCE_ROW(_("Font"), btn_font); 194 | 195 | // foreground 196 | GtkWidget* btn_foreground = (pTab->style.foreground_color) 197 | ? gtk_color_button_new_with_rgba(pTab->style.foreground_color) 198 | : gtk_color_button_new(); 199 | g_signal_connect(btn_foreground, "color-set", G_CALLBACK(dlg_set_foreground), pTab); 200 | TERMIT_PREFERENCE_ROW(_("Foreground"), btn_foreground); 201 | 202 | // background 203 | GtkWidget* btn_background = (pTab->style.background_color) 204 | ? gtk_color_button_new_with_rgba(pTab->style.background_color) 205 | : gtk_color_button_new(); 206 | g_signal_connect(btn_background, "color-set", G_CALLBACK(dlg_set_background), pTab); 207 | TERMIT_PREFERENCE_ROW(_("Background"), btn_background); 208 | 209 | // audible_bell 210 | GtkWidget* btn_audible_bell = gtk_check_button_new(); 211 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn_audible_bell), pTab->audible_bell); 212 | g_signal_connect(btn_audible_bell, "toggled", G_CALLBACK(dlg_set_audible_bell), pTab); 213 | TERMIT_PREFERENCE_ROW(_("Audible bell"), btn_audible_bell); 214 | 215 | // apply to al tabs 216 | GtkWidget* btn_apply_to_all_tabs = gtk_check_button_new(); 217 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn_apply_to_all_tabs), FALSE); 218 | g_signal_connect(btn_apply_to_all_tabs, "toggled", G_CALLBACK(dlg_set_apply_to_all_tabs), &apply_to_all_tabs_flag); 219 | TERMIT_PREFERENCE_ROW(_("Apply to all tabs"), btn_apply_to_all_tabs); 220 | 221 | GtkWidget* btn_restore = gtk_button_new_from_icon_name("document-revert", GTK_ICON_SIZE_BUTTON); 222 | g_signal_connect(G_OBJECT(btn_restore), "clicked", G_CALLBACK(dlg_restore_defaults), hlp); 223 | gtk_grid_attach(GTK_GRID(grid), btn_restore, 0, row, 2, 1); 224 | 225 | gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), grid); 226 | 227 | gtk_widget_show_all(dialog); 228 | if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) { 229 | dlg_set_tab_default_values(pTab, hlp); 230 | } else { 231 | if (apply_to_all_tabs_flag) { 232 | gint page_num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(termit.notebook)); 233 | gint i=0; 234 | for (; itab_name)); 243 | // insane title flag 244 | if (pTab->title || 245 | (!pTab->title && 246 | strcmp(gtk_label_get_text(GTK_LABEL(label)), 247 | gtk_entry_get_text(GTK_ENTRY(entry_title))) != 0)) { 248 | termit_tab_set_title(pTab, gtk_entry_get_text(GTK_ENTRY(entry_title))); 249 | } 250 | } 251 | termit_dlg_helper_free(hlp); 252 | gtk_widget_destroy(dialog); 253 | } 254 | -------------------------------------------------------------------------------- /src/termit_style.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include "termit_style.h" 23 | 24 | void termit_style_init(struct TermitStyle* style) 25 | { 26 | style->font_name = g_strdup("Monospace 10"); 27 | style->font = pango_font_description_from_string(style->font_name); 28 | style->foreground_color = NULL; 29 | style->background_color = NULL; 30 | style->colors = NULL; 31 | style->colors_size = 0; 32 | } 33 | 34 | void termit_style_free(struct TermitStyle* style) 35 | { 36 | g_free(style->font_name); 37 | pango_font_description_free(style->font); 38 | if (style->colors) { 39 | g_free(style->colors); 40 | } 41 | if (style->background_color) { 42 | gdk_rgba_free(style->background_color); 43 | } 44 | if (style->foreground_color) { 45 | gdk_rgba_free(style->foreground_color); 46 | } 47 | struct TermitStyle tmp = {}; 48 | *style = tmp; 49 | } 50 | 51 | void termit_style_copy(struct TermitStyle* dest, const struct TermitStyle* src) 52 | { 53 | dest->font_name = g_strdup(src->font_name); 54 | dest->font = pango_font_description_from_string(src->font_name); 55 | if (src->background_color) { 56 | dest->background_color = gdk_rgba_copy(src->background_color); 57 | } else { 58 | dest->background_color = NULL; 59 | } 60 | if (src->foreground_color) { 61 | dest->foreground_color = gdk_rgba_copy(src->foreground_color); 62 | } else { 63 | dest->foreground_color = NULL; 64 | } 65 | if (src->colors_size) { 66 | dest->colors = g_memdup2(src->colors, src->colors_size * sizeof(GdkRGBA)); 67 | dest->colors_size = src->colors_size; 68 | } else { 69 | dest->colors = NULL; 70 | dest->colors_size = 0; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/termit_style.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2007-2023 Evgeny Ratnikov 2 | * 3 | * This program is free software: you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation, either version 3 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | */ 16 | 17 | #ifndef TERMIT_STYLE_H 18 | #define TERMIT_STYLE_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | struct TermitStyle 26 | { 27 | gchar* font_name; 28 | PangoFontDescription* font; 29 | GdkRGBA* foreground_color; 30 | GdkRGBA* background_color; 31 | GdkRGBA* colors; 32 | glong colors_size; 33 | }; 34 | 35 | void termit_style_init(struct TermitStyle* style); 36 | void termit_style_copy(struct TermitStyle* dest, const struct TermitStyle* src); 37 | void termit_style_free(struct TermitStyle* style); 38 | 39 | #endif /* TERMIT_STYLE_H */ 40 | -------------------------------------------------------------------------------- /utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright © 2007-2023 Evgeny Ratnikov 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | # Slackware SlackBuild 17 | CONFIGURE_FILE(termit.SlackBuild.in ${TERMIT_SOURCE_DIR}/utils/termit.SlackBuild @ONLY) 18 | # Fedora spec 19 | CONFIGURE_FILE(termit.spec.in ${TERMIT_SOURCE_DIR}/utils/termit.spec @ONLY) 20 | 21 | -------------------------------------------------------------------------------- /utils/slack-desc: -------------------------------------------------------------------------------- 1 | |-----handy-ruler------------------------------------------------------| 2 | termit: termit (terminal emulator) 3 | termit: 4 | termit: Small terminal emulator configurable via Lua. 5 | termit: Other dependencies are Vte and Gtk2 libs. 6 | termit: Termit supports multiple tabs, encoding switching and sessions. 7 | termit: 8 | termit: http://wiki.github.com/nonstop/termit/ 9 | termit: 10 | -------------------------------------------------------------------------------- /utils/termit.SlackBuild.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Slackware build script for termit 4 | 5 | # Written by Evgeny Ratnikov (ratnikov dot ev at gmail dot com) 6 | 7 | PRGNAM=termit 8 | VERSION=${VERSION:-"@TERMIT_PACKAGE_VERSION@"} 9 | ARCH=${ARCH:-i686} 10 | BUILD=${BUILD:-1} 11 | TAG=${TAG:-_SBo} 12 | 13 | CWD=$(pwd) 14 | TMP=${TMP:-/tmp/$TAG} 15 | PKG=$TMP/package-$PRGNAM 16 | OUTPUT=${OUTPUT:-/tmp} 17 | 18 | if [ "$ARCH" = "i486" ]; then 19 | SLKCFLAGS="-O2 -march=i486 -mtune=i686" 20 | elif [ "$ARCH" = "i686" ]; then 21 | SLKCFLAGS="-O2 -march=i686 -mtune=i686" 22 | elif [ "$ARCH" = "x86_64" ]; then 23 | SLKCFLAGS="-O2 -fPIC" 24 | fi 25 | 26 | set -e 27 | 28 | rm -rf $PKG 29 | mkdir -p $TMP $PKG $OUTPUT 30 | cd $TMP 31 | rm -rf $PRGNAM-$VERSION 32 | tar xvf $CWD/$PRGNAM-$VERSION.tar.bz2 33 | cd $PRGNAM-$VERSION 34 | find . \ 35 | \( -perm 777 -o -perm 775 -o -perm 711 -o -perm 555 -o -perm 511 \) \ 36 | -exec chmod 755 {} \; -o \ 37 | \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \ 38 | -exec chmod 644 {} \; 39 | 40 | CFLAGS="$SLKCFLAGS" CXXFLAGS="$SLKCFLAGS" cmake -DCMAKE_INSTALL_PREFIX=/usr . 41 | 42 | make 43 | make install DESTDIR=$PKG 44 | 45 | ( cd $PKG 46 | find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true 47 | find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true 48 | ) 49 | 50 | mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION 51 | cp -a ChangeLog INSTALL COPYING TODO $PKG/usr/doc/$PRGNAM-$VERSION 52 | cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild 53 | cat $CWD/slack-desc > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.slack-desc 54 | 55 | mkdir -p $PKG/install 56 | cat $CWD/slack-desc > $PKG/install/slack-desc 57 | 58 | cd $PKG 59 | chown -R root:root . 60 | /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.tgz 61 | 62 | -------------------------------------------------------------------------------- /utils/termit.ebuild: -------------------------------------------------------------------------------- 1 | # Copyright 1999-2008 Gentoo Foundation 2 | # Distributed under the terms of the GNU General Public License v2 3 | # $Header: $ 4 | 5 | EAPI=2 6 | 7 | CMAKE_MIN_VERSION="2.6.1" 8 | 9 | inherit cmake-utils 10 | 11 | SRC_URI="https://github.com/nonstop/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" 12 | HOMEPAGE="http://wiki.github.com/nonstop/termit/" 13 | DESCRIPTION="Simple terminal emulator based on vte library with Lua scripting." 14 | 15 | RDEPEND=">=x11-libs/vte-0.42.5 16 | >=x11-libs/gtk+-3.18 17 | >=dev-lang/lua-5.2" 18 | DEPEND="${RDEPEND}" 19 | 20 | SLOT="0" 21 | LICENSE="GPL-3" 22 | KEYWORDS="~x86 ~amd64" 23 | IUSE="" 24 | 25 | DOCS="INSTALL ChangeLog doc/README doc/rc.lua.example doc/lua_api.txt" 26 | 27 | CMAKE_IN_SOURCE_BUILD="yes" 28 | 29 | pkg_postinst() { 30 | einfo 31 | einfo "There is a example of configfile in " 32 | einfo " /usr/share/doc/termit/rc.lua.example " 33 | einfo "Copy this file to " 34 | einfo " \$HOME/.config/termit/rc.lua" 35 | einfo "and modify to fit your needs." 36 | einfo 37 | } 38 | -------------------------------------------------------------------------------- /utils/termit.spec.in: -------------------------------------------------------------------------------- 1 | Summary: termit (terminal emulator) 2 | Name: termit 3 | Version: @TERMIT_PACKAGE_VERSION@ 4 | Release: 1%{?dist} 5 | License: GPLv3 6 | URL: http://wiki.github.com/nonstop/termit/ 7 | Group: System Environment/Base 8 | Source: %{name}-%{version}.tar.bz2 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 10 | 11 | BuildRequires: gtk3-devel >= 3.18 12 | BuildRequires: vte-devel >= 0.42.5 13 | BuildRequires: lua-devel >= 5.2 14 | BuildRequires: cmake desktop-file-utils gettext 15 | 16 | %description 17 | Small terminal emulator. The only dependencies are Vte and Gtk3 libs. 18 | Termit supports tabs, bookmarks, encoding switching and sessions. 19 | 20 | %prep 21 | %setup -q 22 | 23 | %build 24 | find . -type f -name CMakeCache.txt -exec rm -rf {} \; 25 | %cmake DCMAKE_INSTALL_DOCDIR=%{_docdir} . 26 | make VERBOSE=1 %{?_smp_mflags} 27 | 28 | %install 29 | rm -rf $RPM_BUILD_ROOT 30 | make install DESTDIR=$RPM_BUILD_ROOT 31 | desktop-file-install \ 32 | --delete-original \ 33 | --remove-category=Utility \ 34 | --add-category=System \ 35 | --dir=${RPM_BUILD_ROOT}%{_datadir}/applications \ 36 | ${RPM_BUILD_ROOT}%{_datadir}/applications/%{name}.desktop 37 | %find_lang %{name} 38 | rm -rf ${RPM_BUILD_ROOT}%{_datadir}/doc/termit/ 39 | 40 | %clean 41 | rm -rf $RPM_BUILD_ROOT 42 | 43 | %files -f %{name}.lang 44 | %defattr(-,root,root,-) 45 | %doc ChangeLog COPYING TODO 46 | %doc doc/README doc/rc.lua.example doc/lua_api.txt doc/termit.svg 47 | %{_bindir}/%{name} 48 | %{_datadir}/applications/%{name}.desktop 49 | %{_mandir}/man1/%{name}.1.* 50 | --------------------------------------------------------------------------------
11 | Small terminal emulator configurable via Lua. 12 | Other dependencies are Vte and Gtk3 libs. 13 | Termit supports multiple tabs, encoding switching and sessions. 14 |