{"id":13530584,"url":"https://github.com/endaaman/tym","last_synced_at":"2025-04-04T06:08:13.142Z","repository":{"id":37385220,"uuid":"86408274","full_name":"endaaman/tym","owner":"endaaman","description":"Lua-configurable terminal emulator","archived":false,"fork":false,"pushed_at":"2025-01-14T07:07:15.000Z","size":592,"stargazers_count":192,"open_issues_count":15,"forks_count":14,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-28T05:11:21.984Z","etag":null,"topics":["gtk3","lua","terminal","terminal-emulator","tym","vte"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/endaaman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-28T02:57:41.000Z","updated_at":"2025-03-21T02:28:15.000Z","dependencies_parsed_at":"2024-05-02T07:51:10.330Z","dependency_job_id":"73940237-7c43-4c70-9c6b-546ecf74f8c0","html_url":"https://github.com/endaaman/tym","commit_stats":{"total_commits":469,"total_committers":19,"mean_commits":24.68421052631579,"dds":0.3411513859275054,"last_synced_commit":"0fa5e5a35d7c07d931a8488375a221ec68db322c"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endaaman%2Ftym","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endaaman%2Ftym/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endaaman%2Ftym/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endaaman%2Ftym/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/endaaman","download_url":"https://codeload.github.com/endaaman/tym/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247128751,"owners_count":20888235,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gtk3","lua","terminal","terminal-emulator","tym","vte"],"created_at":"2024-08-01T07:00:52.132Z","updated_at":"2025-04-04T06:08:13.126Z","avatar_url":"https://github.com/endaaman.png","language":"C","funding_links":[],"categories":["Uncategorized","Packages"],"sub_categories":["Uncategorized","Terminals"],"readme":"# tym\n\n[![CircleCI](https://circleci.com/gh/endaaman/tym.svg?style=svg)](https://circleci.com/gh/endaaman/tym) [![Discord](https://img.shields.io/discord/1065853670371119124?label=chat%20on%20discord)](https://discord.gg/Ftt8PGYmJY)\n\n`tym` is a Lua-configurable terminal emulator base on [VTE](https://gitlab.gnome.org/GNOME/vte).\n\n## Installation\n\n### Arch Linux\n\n```\n$ yay -S tym\n```\n\n### NixOS\n\n```\n$ nix-env -iA nixos.tym\n```\n\n### Other distros\n\nDownload the latest release from [Releases](https://github.com/endaaman/tym/releases), extract it and run as below\n\n```\n$ ./configure\n$ sudo make install\n```\n\n\u003cdetails\u003e\u003csummary\u003eBuild dependencies (click to open)\u003c/summary\u003e\n\u003cp\u003e\n\n#### Arch Linux\n\n```\n$ sudo pacman -S vte3 lua53\n```\n\n#### Ubuntu\n\n```\n$ sudo apt install libgtk-3-dev libvte-2.91-dev liblua5.3-dev libpcre2-dev\n```\n\n#### Void Linux\n```\n$ sudo xbps-install -S vte3-devel lua-devel\n```\n\n#### Other distros / macOS / Windows\n\nWe did not check which packages are needed to build on other distros or OS. We are waiting for your contribution ;)\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n## Configuration\n\nIf `$XDG_CONFIG_HOME/tym/config.lua` exists, it is executed when the app starts. You can change the path with the `--use`/`-u` option.\n\n```lua\n-- At first, you need to require tym module\nlocal tym = require('tym')\n\n-- set individually\ntym.set('width', 100)\n\ntym.set('font', 'DejaVu Sans Mono 11')\n\n-- set by table\ntym.set_config({\n  shell = '/usr/bin/fish',\n  cursor_shape = 'underline',\n  autohide = true,\n  color_foreground = 'red',\n})\n```\n\nSee [wiki](https://github.com/endaaman/tym/wiki) to check out the advanced examples.\n\nAll available config values are shown below.\n\n| field name | type | default value | description |\n| --- | --- | --- | --- |\n| `shell` | string | `$SHELL` → `vte_get_user_shell()` → `'/bin/sh'` | Shell to execute. |\n| `term` | string | `'xterm-256color'` | Value of `$TERM`. |\n| `title` | string | `'tym'` | Initial window title. |\n| `font` | string | `''` | You can specify font with `'FAMILY-LIST [SIZE]'`, for example `'Ubuntu Mono 12'`. The value is parsed by [`pango_font_description_from_string()`](https://developer.gnome.org/pango/stable/pango-Fonts.html#pango-font-description-from-string). If empty string is set, the system default fixed width font will be used. |\n| `icon` | string | `'utilities-terminal'` | Name of icon. cf. [Icon Naming Specification](https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html) |\n| `role` | string | `''` | Unique identifier for the window. If empty string is set, no value set. (cf. [gtk_window_set_role()](https://developer.gnome.org/gtk3/stable/GtkWindow.html#gtk-window-set-role)) |\n| `cursor_shape` | string | `'block'` | `'block'`, `'ibeam'` or `'underline'` can be used. |\n| `cursor_blink_mode` | string | `'system'` | `'system'`, `'on'` or `'off'` can be used. |\n| `cjk_width` | string | `'narrow'` | `'narrow'` or `'wide'` can be used. |\n| `background_image` | string | `''` | Path to background image file. |\n| `uri_schemes` | string | `'http https file mailto'` | Space-separated list of URI schemes to be highlighted and clickable. Specify empty string to disable highlighting. Specify `'*'` to accept any strings valid as schemes (according to RFC 3986). |\n| `width` | integer | `80` | Initial columns. |\n| `height` | integer | `22` | Initial rows. |\n| `scale` | integer | `100` | Font scale in **percent(%)** |\n| `cell_width` | integer | `100` | Cell width scale in **percent(%)**. |\n| `cell_height` | integer | `100` | Cell height scale in **percent(%)**.  |\n| `padding_top`  | integer | `0` | Top padding. |\n| `padding_bottom`  | integer | `0` | Bottom padding. |\n| `padding_left`  | integer | `0` | Left padding. |\n| `padding_right`  | integer | `0` | Right padding. |\n| `scrollback_length` | integer | `512` | Length of the scrollback buffer. |\n| `scrollback_on_output` | boolean | `true` | Whether to scroll the buffer when the new data is output. |\n| `ignore_default_keymap` | boolean | `false` | Whether to use default keymap. |\n| `autohide` | boolean | `false` | Whether to hide mouse cursor when the user presses a key. |\n| `silent` | boolean | `false` | Whether to beep when bell sequence is sent. |\n| `bold_is_bright` | boolean | `false` | Whether to make bold texts bright. |\n| `color_window_background` | string | `''` | Color of the terminal window. It is seen when `'padding_horizontal'` `'padding_vertical'` is not `0`. If you set `'NONE'`, the window background will not be drawn. |\n| `color_foreground`, `color_background`, `color_cursor`, `color_cursor_foreground`, `color_highlight`, `color_highlight_foreground`, `color_bold`, `color_0` ... `color_15` | string | [See the next section](#user-content-theme-customization) | You can specify standard color string such as `'#f00'`, `'#ff0000'`, `'rgba(22, 24, 33, 0.7)'` or `'red'`. It will be parsed by [`gdk_rgba_parse()`](https://developer.gnome.org/gdk3/stable/gdk3-RGBA-Colors.html#gdk-rgba-parse). If empty string is set, the VTE default color will be used. If you set `'NONE'` for `color_background`, the terminal background will not be drawn.|\n\n\n## Theme customization\n\nWhen `$XDG_CONFIG_HOME/tym/theme.lua` exists, it is loaded **before** loading config. You can change the path by using the `--theme`/`-t` option. The following is an example, whose color values are built-in default. They were ported from [iceberg](https://cocopon.github.io/iceberg.vim/).\n\n```lua\nlocal bg = '#161821'\nlocal fg = '#c6c8d1'\nreturn {\n  color_background = bg,\n  color_foreground = fg,\n  color_bold = fg,\n  color_cursor = fg,\n  color_cursor_foreground = bg,\n  color_highlight = fg,\n  color_highlight_foreground = bg,\n  color_0  = bg,\n  color_1  = '#e27878',\n  color_2  = '#b4be82',\n  color_3  = '#e2a478',\n  color_4  = '#84a0c6',\n  color_5  = '#a093c7',\n  color_6  = '#89b8c2',\n  color_7  = fg,\n  color_8  = '#6b7089',\n  color_9  = '#e98989',\n  color_10 = '#c0ca8e',\n  color_11 = '#e9b189',\n  color_12 = '#91acd1',\n  color_13 = '#ada0d3',\n  color_14 = '#95c4ce',\n  color_15 = '#d2d4de',\n}\n```\n\nYou need to return the color map as table.\n\n\u003cdetails\u003e\u003csummary\u003eColor correspondence (click to open)\u003c/summary\u003e\n\u003cdiv\u003e\n\n```\ncolor_0  : black (background)\ncolor_1  : red\ncolor_2  : green\ncolor_3  : brown\ncolor_4  : blue\ncolor_5  : purple\ncolor_6  : cyan\ncolor_7  : light gray (foreground)\ncolor_8  : gray\ncolor_9  : light red\ncolor_10 : light green\ncolor_11 : yellow\ncolor_12 : light blue\ncolor_13 : pink\ncolor_14 : light cyan\ncolor_15 : white\n```\n\n\u003c/div\u003e\n\u003c/details\u003e\n\n\n## Keymap\n\n### Default keymap\n\n| Key             | Action                       |\n| :-------------- | :--------------------------- |\n| Ctrl Shift c    | Copy selection to clipboard. |\n| Ctrl Shift v    | Paste from clipboard.        |\n| Ctrl Shift r    | Reload config file.          |\n\n### Customizing keymap\n\nYou can register keymap(s) using `tym.set_keymap(accelerator, func)` or `tym.set_keymaps(table)`. `accelerator` must be in a format parsable by [gtk_accelerator_parse()](https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accelerator-parse). If a truthy value is returned, the event propagation will **not be stopped**.\n\n```lua\n-- also can set keymap\ntym.set_keymap('\u003cCtrl\u003e\u003cShift\u003eo', function()\n  local h = tym.get('height')\n  tym.set('height', h + 1)\n  tym.notify('Set window height :' .. h)\nend)\n\n-- set by table\ntym.set_keymaps({\n  ['\u003cCtrl\u003e\u003cShift\u003et'] = function()\n    tym.reload()\n    tym.notify('reload config')\n  end,\n  ['\u003cCtrl\u003e\u003cShift\u003ev'] = function()\n    -- reload and notify\n    tym.send_key('\u003cCtrl\u003e\u003cShift\u003et')\n  end,\n\n  ['\u003cShift\u003ey'] = function()\n    tym.notify('Y has been pressed')\n    return true -- notification is shown and `Y` will be inserted\n  end,\n  ['\u003cShift\u003ew'] = function()\n    tym.notify('W has been pressed')\n    -- notification is shown but `W` is not inserted\n  end,\n})\n```\n\n## Lua API\n\n| Name                                 | Return value | Description |\n| ------------------------------------ | ------------ | ----------- |\n| `tym.get(key)`                       | any      | Get config value. |\n| `tym.set(key, value)`                | void     | Set config value. |\n| `tym.get_default_value(key)`         | any      | Get default config value. |\n| `tym.get_config()`                   | table    | Get whole config. |\n| `tym.set_config(table)`              | void     | Set config by table. |\n| `tym.reset_config()`                 | void     | Reset all config. |\n| `tym.set_keymap(accelerator, func)`  | void     | Set keymap. |\n| `tym.unset_keymap(accelerator)`      | void     | Unset keymap. |\n| `tym.set_keymaps(table)`             | void     | Set keymaps by table. |\n| `tym.reset_keymaps()`                | void     | Reset all keymaps. |\n| `tym.set_hook(hook_name, func)`      | void     | Set a hook. |\n| `tym.set_hooks(table)`               | void     | Set hooks. |\n| `tym.reload()`                       | void     | Reload config file.|\n| `tym.reload_theme()`                 | void     | Reload theme file. |\n| `tym.send_key()`                     | void     | Send key press event. |\n| `tym.signal(id, hook, {param...})`   | void     | Send signal to the tym instance specified by id. |\n| `tym.set_timeout(func, interval=0)`  | int(tag) | Set timeout. return true in func to execute again. |\n| `tym.clear_timeout(tag)`             | void     | Clear the timeout. |\n| `tym.put(text)`                      | void     | Feed text. |\n| `tym.bell()`                         | void     | Sound bell. |\n| `tym.open(uri)`                      | void     | Open URI via your system default app like `xdg-open(1)`. |\n| `tym.notify(message, title='tym')`   | void     | Show desktop notification. |\n| `tym.copy(text, target='clipboard')` | void     | Copy text to clipboard. As `target`, `'clipboard'`, `'primary'` or `secondary` can be used. |\n| `tym.copy_selection(target='clipboard')` | void | Copy current selection. |\n| `tym.paste(target='clipboard')`      | void     | Paste clipboard. |\n| `tym.check_mod_state(accelerator)`   | bool     | Check if the mod key(such as `'\u003cCtrl\u003e'` or `\u003cShift\u003e`) is being pressed. |\n| `tym.color_to_rgba(color)`           | r, g, b, a | Convert color string to RGB bytes and alpha float using [`gdk_rgba_parse()`](https://developer.gnome.org/gdk3/stable/gdk3-RGBA-Colors.html#gdk-rgba-parse). |\n| `tym.rgba_to_color(r, g, b, a)`      | string   | Convert RGB bytes and alpha float to color string like `rgba(255, 128, 0, 0.5)` can be used in color option such as `color_background`. |\n| `tym.rgb_to_hex(r, g, b)`            | string   | Convert RGB bytes to 24bit HEX like `#ABCDEF`. |\n| `tym.hex_to_rgb(hex)`                | r, g, b  | Convert 24bit HEX like `#ABCDEF` to RGB bytes. |\n| `tym.get_monitor_model()`            | string   | Get monitor model on which the window is shown. |\n| `tym.get_cursor_position()`          | int, int | Get where column and row the cursor is. |\n| `tym.get_clipboard(target='clipboard')` | string | Get content in the clipboard. |\n| `tym.get_selection()`                | string   | Get selected text. |\n| `tym.has_selection()`                | bool     | Get if selected. |\n| `tym.select_all()`                   | void     | Select all texts. |\n| `tym.unselect_all()`                 | void     | Unselect all texts. |\n| `tym.get_text(start_row, start_col, end_row, end_col)` | string | Get text on the terminal screen. If you set `-1` to `end_row` and `end_col`, the target area will be the size of termianl. |\n| `tym.get_config_path()`              | string   | Get full path to config file. |\n| `tym.get_theme_path()`               | string   | Get full path to theme file. |\n| `tym.get_terminal_pid()`             | integer  | Get terminal pid. |\n| `tym.get_pid()`                      | integer  | Get child pid(usually shell's pid). |\n| `tym.get_ids()`                      | table[int] | Get tym instance ids. |\n| `tym.get_version()`                  | string   | Get version string. |\n\n### Hooks\n\n| Name | Param | Default action | Description |\n| --- | --- | --- | --- |\n| `title`       | title  | changes title | If string is returned, it will be used as the new title. |\n| `bell`        | nil    | makes the window urgent when it is inactive. | If true is returned, the window will not be urgent. |\n| `clicked`     | button, uri | If URI exists under cursor, opens it | Triggered when mouse button is pressed. |\n| `scroll`      | delta_x, delta_y, mouse_x, mouse_y  | scroll buffer | Triggered when mouse wheel is scrolled. |\n| `drag`        | filepath  | feed filepath to the console | Triggered when files are dragged to the screen. |\n| `activated`   | nil    | nothing | Triggered when the window is activated. |\n| `deactivated` | nil    | nothing | Triggered when the window is deactivated. |\n| `resized`     | nil    | nothing | Triggered when the window is resized. |\n| `selected`    | string | nothing | Triggered when the text in the terminal screen is selected. |\n| `unselected`  | nil    | nothing | Triggered when the selection is unselected. |\n| `signal`      | string | nothing | Triggered when `me.endaaman.tym.hook` signal is received. |\n\nIf truthy value is returned in a callback function, the default action will be **stopped**.\n\n```lua\ntym.set_hooks({\n  title = function(t)\n    tym.set('title', 'tym - ' .. t)\n    return true -- this is needed to cancenl default title application\n  end,\n})\n\n--- NOTE:\n-- If you set the hook to 'clicked' handler, you need to open URI manually like below,\ntym.set_hook('clicked', function(button, uri)\n  print('you pressed button:', button) -- 1:left, 2:middle, 3:right\n\n  -- open URI only by middle click\n  if button == 2 then\n    if uri then\n      print('you clicked URI: ', uri)\n      tym.open(uri)\n      -- disable the default action 'put clipboard' when open URI\n      return true\n    end\n  end\nend)\n```\n\n## Interprocess communication using D-Bus\n\nEach tym window has an unique ID, which can be checked by `tym.get_id()` or `$TYM_ID`, and also listen to D-Bus signal/method call on the path `/me/endaaman/tym\u003cID\u003e` and the interface name `me.endaaman.tym`.\n\n### Signals\n\n| Name | Input(D-Bus signature) | Description |\n| ---- | --- | --- |\n| `hook` | `s` | Triggers `signal` hook. |\n\nFor example, when you prepare the following config and command,\n\n```lua\nlocal tym = require('tym')\ntym.set_hook('signal', function (p)\n  print('Hello from DBus signal')\n  print('param:', p)\nend)\n```\n\n```\n$ dbus-send /me/endaaman/tym0 me.endaaman.tym.hook string:'THIS IS PARAM'\n```\n\nor\n\n```lua\ntym.signal(0, 'hook', {'THIS IS PARAM'}) -- NOTICE: param must be table\n```\n\nyou will get an output like below.\n\n```\nHello from DBus signal\nparam:  THIS IS PARAM\n```\n\nAlternatively, you can use `tym` command to send signal.\n\n```\n$ tym --signal hook --dest 0 --param 'THIS IS PARAM'\n```\n\nIf the target window is its own one, it will the value of `$TYM_ID` and `--dest` can be omitted. So it is enough like below.\n\n```\n$ tym --signal hook --param 'THIS IS PARAM'\n```\n\n\n### Methods\n\n| Name | Input (D-Bus signature) | Output (D-Bus signature) | Description |\n| ---- | --- | --- | --- |\n| `get_ids` | None | `ai` | Get all tym instance IDs. |\n| `echo` | `s` | `s` | Echo output the same as input. |\n| `eval` | `s` | `s` | Evaluate one line lua script. `return` is needed. |\n| `eval_file` | `s` | `s` | Evaluate a script file. `return` is needed. |\n| `exec` | `s` | None | Execute one line lua script without outputs. |\n| `eval_file` | `s` | None | Execute a script filt without outputs. |\n\n\nFor example, when you exec the command,\n\n```\n$ dbus-send --print-reply --type=method_call --dest=me.endaaman.tym /me/endaaman/tym0 me.endaaman.tym.eval string:'return \"title is \" .. tym.get(\"title\")'\n```\n\nthen you will get like below.\n\n```\nmethod return time=1646287109.007168 sender=:1.3633 -\u003e destination=:1.3648 serial=39 reply_serial=2\n   string \"title is tym\"\n```\n\nAs same as signals, you can use `tym` command to execute method calling.\n\n```\n$ tym --call eval --dest 0 --param 'return \"title is \" .. tym.get(\"title\")'\n```\n\nOf course, `--dest` can be omitted as well.\n\n\n## Options\n\n### `--help` `-h`\n\n```\n$ tym -h\n```\n\n### `--use=\u003cpath\u003e` `-u \u003cpath\u003e`\n\n```\n$ tym --use=/path/to/config.lua\n```\n\nIf `NONE` is provided, all config will be default (user-defined config file will not be loaded).\n\n```\n$ tym -u NONE\n```\n\n### `--theme=\u003cpath\u003e` `-t \u003cpath\u003e`\n\n```\n$ tym --use=/path/to/theme.lua\n```\n\nIf `NONE` is provided, default theme will be used.\n\n```\n$ tym -t NONE\n```\n\n### `--signal=\u003csignal name\u003e` `-s \u003csignal name\u003e`\n\n```\n$ tym --signal hook\n```\n\nSends a D-Bus signal to the current instance (determined by `$TYM_ID` environment value). To send to another instance, use `--dest` (or `-d`) option.\n\n\n### `--call=\u003cmethod name\u003e` `-c \u003cmethod name\u003e`\n\nCalls D-Bus method of the current instance (determined by `$TYM_ID` environment value). To call it of another instance, provide `--dest` (or `-d`) option.\n\n```\n$ tym --call eval --param 'return 1 + 2'\n```\n\n### `--daemon`\n\nThis makes tym a daemon process, which has no window or application context.\n\n```\n$ tym --daemon\n```\n\nTo enable the daemon feature, set `tym-daemon.desktop` as auto-started on the DE's settings or add the line `tym --daemon \u0026` in your `.xinitrc`.\n\n\n### `--cwd=\u003cpath\u003e`\n\nThis sets the terminal's working directory. `\u003cpath\u003e` must be an absolute path. If unspecified `tym` will use the current working directory of the terminal invocation.\n\n```console\n$ tym --cwd=/home/user/projects\n```\n\n### `--\u003cconfig option\u003e`\n\nYou can set config value via command line option.\n\n```console\n$ tym --shell=/bin/zsh --color_background=red --width=40 --ignore_default_keymap\n```\n\n### `--isolated`\n\n```console\n$ tym --isolated\n```\n\nThis option enables tym to create a separate process for each instance. Then an app instance will be isolated from D-Bus and no longer have ability to handle D-Bus signals/method calls.\n\n\n### `--` (\"double dash\" option)\n\ntym also accepts double dash `--` option as the command line to spawn.\n\n```console\n$ tym -- less -N Dockerfile\n```\n\n## Development\n\nClone this repo and run as below\n\n```console\n$ autoreconf -fvi\n$ ./configure --enable-debug\n$ make \u0026\u0026 ./src/tym -u ./path/to/config.lua   # for debug\n$ make check; cat src/tym-test.log            # for unit tests\n```\n\nRun tests in docker container\n\n```console\n$ docker build -t tym .\n$ docker run tym\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fendaaman%2Ftym","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fendaaman%2Ftym","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fendaaman%2Ftym/lists"}