{"id":16694511,"url":"https://github.com/foxfriends/syncat-themes","last_synced_at":"2026-02-19T23:01:10.206Z","repository":{"id":83353694,"uuid":"172181468","full_name":"foxfriends/syncat-themes","owner":"foxfriends","description":"Themes for Syncat","archived":false,"fork":false,"pushed_at":"2025-04-21T19:07:34.000Z","size":102,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-21T20:25:18.223Z","etag":null,"topics":["cat","command-line","highlighting","style","syntax","terminal","tool"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/foxfriends.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2019-02-23T06:44:29.000Z","updated_at":"2025-04-21T19:07:38.000Z","dependencies_parsed_at":"2025-04-22T04:15:47.330Z","dependency_job_id":null,"html_url":"https://github.com/foxfriends/syncat-themes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/foxfriends/syncat-themes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fsyncat-themes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fsyncat-themes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fsyncat-themes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fsyncat-themes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foxfriends","download_url":"https://codeload.github.com/foxfriends/syncat-themes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fsyncat-themes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29636035,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T22:32:43.237Z","status":"ssl_error","status_checked_at":"2026-02-19T22:32:38.330Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cat","command-line","highlighting","style","syntax","terminal","tool"],"created_at":"2024-10-12T16:46:22.418Z","updated_at":"2026-02-19T23:01:10.187Z","avatar_url":"https://github.com/foxfriends.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"[Tree-sitter]: https://github.com/tree-sitter/tree-sitter\n[Syncat]: https://github.com/foxfriends/syncat\n[syncat.kak]: https://github.com/foxfriends/config/blob/kak/autoload/filetype/syncat.kak\n\n# Syncat Themes\n\nStylesheets and themes for [Syncat][], the syntax aware cat tool. See the Syncat documentation for more\ninformation on how to install and use Syncat.\n\nNote that depending on the settings and features of your terminal program, certain features may not\nappear how you expect them to.\n\n## Installing stylesheets\n\nSyncat stylesheets are installed by placing them in the relevant configuration directory for your\noperating system:\n\n*   Linux: `$HOME/.config/syncat/style/active`\n*   Mac: `$HOME/Library/Preferences/com.cameldridge.syncat/style/active`\n*   Windows: Not officially supported\n\nIn particular, to install these stylesheets, clone this repository to the `syncat/style` directory.\n\n```\ncd ~/.config/syncat\ngit clone https://github.com/foxfriends/syncat-themes style\n```\n\n## Selecting a theme\n\nThe themes in this repository implemented in two parts. In the `base` directory are the actual\nfiletype stylesheets, each of which requires the file `../colours.syncat` to exist, defining the\ncolours which are used. These `colours.syncat` files are defined in each of the other directories,\nlisting the relevant colours definitions for that theme, so one must be symlinked to the right\nlocation for the themes to work, for example, if you like `onedark`:\n\n```bash\nln -s ./base ./active\nln -s ./onedark/colours.syncat ./colours.syncat\n```\n\nPlease note that at this time, not every filetype has been implemented, and not all the existing\nstylesheets are perfect. If anyone would take the time to improve any aspect of these themes, please\nfeel free to submit a pull request with your improvements.\n\n# Creating themes\n\nSyncat supports the `--dev` option, which will print an s-expression describing the syntax tree,\nrather than printing the actual contents of the file. By creating files demonstrating the syntax\nyou would like to highlight and then printing the syntax tree, you can figure out how to describe\na stylesheet for those files, which are written in a `.syncat` \"syncat stylesheet\".\n\n## `.syncat` Stylesheets\n\nA `.syncat` stylesheet looks, feels, and works very similarly to a CSS file.\n\nSyncat files can, of course, be highlighted by using Syncat, which can be useful for debugging.\nThere is also a highlighter defined for the `Kakoune` text editor [here][syncat.kak].\n\nThese files correspond to one language each, identified by the file name. These names are based\non the `name` entry in the `languages.toml` file of your Syncat configuration. See the [Syncat][]\ndocumentation for more info on the `languages.toml` file.\n\n## Syntax\n\nA `.syncat` file consists three kinds of items:\n\n```\n// imports\nimport \u003cstring\u003e;\n\n// variable declarations\n\u003cvariable\u003e: \u003cvalue\u003e;\n\n// rules\n\u003cselector\u003e {\n    \u003cstyle\u003e: \u003cvalue\u003e;\n    // ...\n}\n```\n\n### Rules\n\nRules consist of a selector (or multiple selectors), followed by a block of style descriptions.\nIf multiple rules match the same subtree, all the styles will be applied. Currently the precedence \nof rules is simply based on the order they are defined in. Styles set by rules near the top of the \nfile will take priority over styles set by rules at the bottom of the file. All imported rules are \nconsidered lower priority to the ones defined in the parent file.\n\n### Selectors\n\nSelectors are the most complex part of the stylesheet. They correspond to paths into the syntax\ntree, similar to how a selector works in HTML/CSS. You can view the syntax tree by passing the `--dev`\noption when running syncat.\n\nHere's an example syntax tree for a trivial piece of code. You can see that they very quickly get\nvery complex. The output from the `--dev` view is not even pretty-printed, but it does include\nthe applied colours!\n\n```javascript\nfunction sayHello(subject) {\n  return `Hello ${subject}`;\n  throw new Error('Unreachable');\n}\n\nconsole.log(sayHello('world'));\n```\n\n```\n(program\n  (function\n    (\"function\")\n    (identifier \"sayHello\")\n    (formal_parameters (\"(\") (identifier \"subject\") (\")\"))\n    (statement_block\n      (\"{\")\n      (return_statement\n        (\"return\")\n          (template_string (\"`\") (template_substitution (\"${\") (identifier \"subject\") (\"}\")) (\"`\"))\n          (\";\"))\n      (throw_statement\n        (\"throw\")\n        (new_expression\n          (\"new\")\n          (identifier \"Error\")\n          (arguments (\"(\") (string (\"'\") (\"'\")) (\")\")))\n        (\";\"))\n      (\"}\")))\n  (expression_statement\n    (call_expression\n      (member_expression (identifier \"console\") (\".\") (property_identifier \"log\"))\n      (arguments\n        (\"(\")\n          (call_expression\n            (identifier \"sayHello\")\n            (arguments (\"(\") (string (\"'\") (\"'\")) (\")\")))\n        (\")\")))\n    (\";\")))\n```\n\n#### Kinds\n\nTo highlight, for example, the function name in blue, you might try the following:\n\n```syncat\nfunction {\n  color: blue;\n}\n```\n\nA selector like this will match that node, as well as all of its children. That is, children will\ninherit all styles from their parent nodes. Unfortunately, this means that the above rule will turn\nthe entire function blue!\n\nIf you only want to match the identifier, and not the other children of the function declaration,\nyou can chain selectors to match children, just like CSS:\n\n```syncat\nfunction identifier {\n  color: blue\n}\n```\n\n#### Direct Child Modifier\n\nUnfortunately, the above selector will still match any identifiers at any depth, including those in the\nmethod body. To get around this, we can use the direct child modifier `\u003e`, similar to the equivalent CSS\nselector, to indicate to only match nodes that are direct children of the specified parent.\n\n```syncat\nfunction \u003e identifier {\n  color: blue;\n}\n```\n\nThere are times when you would rather not apply a style to all children. One common instance of\nthis is for template strings: you don't want to highlight the interpolated text the same colour as\nthe string. You can end a rule with the `\u003e` to ensure that this style does not get applied to any\nchild nodes, only the one matched directly by this selector.\n\n```syncat\ntemplate_string \u003e {\n  color: green;\n}\n```\n\n#### Tokens\n\nTo match specific tokens (the quoted parts in the token tree above), you can use strings in your\nselector. Though it makes most sense to match tokens directly, you can actually use a string to\nmatch against the source text of any node in the tree, even though that text is not visible in the\nprinted s-expression. When this would be useful I don't know, but it maybe worth noting.\n\nFor example, to turn the function keyword purple, you could do the following:\n\n```syncat\n\"function\" {\n  color: purple;\n}\n```\n\nThere are often many elements you would want to style in the same way, so to make things easier, you\ncan write a list of selectors separated by commas:\n\n```syncat\n\"function\", \"return\" {\n  color: purple;\n}\n```\n\nRegular expressions are supported to match a pattern against the token contents. To get all\nidentifiers that start with `say`, we could try something like the following:\n\n```syncat\n/^say[\\w+]$/ {\n  color: cyan;\n}\n```\n\n#### Also modifier\n\nSometimes you would want to highlight a node only if it matches two selectors, typically to match\na node with a specific kind and token. To do this, use the also modifier `\u0026`. This is most useful\nwith a regular expression to get across the intention more clearly.\n\nThis is probably a more correct way to try and highlight all identifiers that start with say.\n\n```syncat\nidentifier \u0026 /^say/ {\n  color: cyan;\n}\n```\n\n#### Sibling modifiers\n\nSometimes it is useful to highlight based on siblings, which is supported by either the `+`\nor `~` modifier. These modifiers work similarly to their CSS counterparts:\n*   `~` will match a node which is a sibling of the previous node\n*   `+` will match a node which immediately follows the previous node\n\nFor example, to match the unreachable `throw` statement in the snippet above, you could try\nthe following:\n\n```syncat\nreturn_statement + throw_statement {\n  background-color: red;\n}\n```\n\n#### \"Any\" node\n\nThe last type of selector not mentioned is the \"any\" selector `*`, which will match any single\nnode.\n\nThis would be a better way of describing \"unreachable\" statements.\n\n```syncat\nreturn_statement ~ * {\n  background-color: red;\n}\n```\n\n#### Grouping\n\nTypically when describing siblings, it can be useful to match more complex siblings than a single\nnode. A group can be used to match an entire sub-selector. For example, to match the arguments\nto the `Error` constructor, but not other functions, you could do this:\n\n```syncat\nnew_expression (identifier \u0026 \"Error\") + arguments * {\n  background-color: red;\n}\n```\n\n### Styles\n\nAs you may have gathered from above, a style just takes the form `\u003cname\u003e: \u003cvalue\u003e;`. Any name\nand value can be supplied together, and will be resolved correctly, it is up to the program that\nis using the stylesheet to determine how those styles are interpreted. In particular, for Syncat,\nthe supported styles are as follows:\n\n*   `color: \u003ccolor\u003e`: The colour of the text\n*   `background-color: \u003ccolor\u003e`: The colour of the background\n*   `reverse: \u003cboolean\u003e`: Reverse the foreground/background colours\n*   `italic: \u003cboolean\u003e`: Use italics\n*   `bold: \u003cboolean\u003e`: Use bold\n*   `underline: \u003cboolean\u003e`: Use underline\n*   `strikethrough: \u003cboolean\u003e`: Use strikethrough\n*   `dim: \u003cboolean\u003e`: Dim the text\n*   `hidden: \u003cboolean\u003e`: Hide the text\n*   `blink: \u003cboolean\u003e`: Have the text blinking\n*   `language: \u003cstring\u003e`: Reparse tokens as another language. The value should be one of the\n    supported syntax file names (above).\n\nUnlike CSS, the final semicolon is not optional.\n\n### Values\n\nThere are 6 kinds of values:\n\n*   `color` values can take one of three forms:\n    *   A color name literal, corresponding to the 16 standard terminal colours (`red`, `green`,\n        `blue`, `cyan`, `yellow`, `purple`, `black`, `white`, `brred`, `brgreen`, `brblue`,\n        `brcyan`, `bryellow`, `brpurple`, `brblack`, `brwhite`)\n    *   A hex colour code, such as `#93df41`. Only the full 6-digit colour codes are supported.\n*   `boolean` values can be either `true` or `false`, and will always default to `false`.\n*   `string` values can be left unquoted if they only contain letters, numbers, _ and -, but must be\n    quoted otherwise. Only double quotes are supported.\n*   `number` values, which are unsigned 32-bit integers. Number values are not used by syncat, but are\n    included anyway.\n*   `variable` values, of the form `$\u003cname\u003e`, which will be resolved to the variable's actual\n    value at runtime.\n*   `capture` values, of the form `$\u003cnumber\u003e`, which will resolve to the numbered regex\n    capture group at runtime. This is a bit complicated, as you could in theory supply multiple\n    regular expressions in your selector. In the end, all the capture groups of each regular\n    expression in the selector are appended together in the order they appear in the selector.\n\n### Variable declarations\n\nThere are two ways to define a new variable. The first is the obvious way. This line will assign\nthe value `blue` to the variable `$function`:\n\n```syncat\n$function: blue;\n```\n\nYou could then use that variable to set all function names to blue:\n\n```syncat\nfunction \u003e identifier { color: $blue; }\n```\n\nVariable values are all computed dynamically (i.e., there is no scope) so the below will\nhave all function names coloured purple, despite the value being set after the rule.\n\n```syncat\n$color: blue;\nfunction \u003e identifier { color: $color; }\n\n$color: purple;\n\"function\", \"return\" { color: $color; }\n```\n\nSimilar to rules, variables defined in the current file will override any variables set in the\nimported files. However, unlike rules, variables defined earlier in the file will be overridden\nby variables defined later. It is just not recommended to define a variable more than once in the\nsame file.\n\n### Named groups\n\nThe second way to define a variable is to use a named group. These variables are set dynamically,\nbased on the text that was matched by some part of a selector. This is most useful for determining\ncertain facts about the sub-tree based on the tree itself.\n\nA named group is a a group that looks like `(\u003cname\u003e selector)`. A variable is defined with the name\nspecified and the value is the text of the matching subtree.\n\nA snippet from the Markdown highlighting shows how this can be used:\n\n```syncat\nfenced_code_block (info_string (\u003clanguage\u003e text)) + code_fence_content {\n    language: $language;\n}\n```\n\n### Imports\n\nImports are typically used to help reuse certain parts of a stylesheet. Most languages define\ncomments the same way, so it would probably be possible to support comments generically, though\nthis has not been done. The imports used by the default themes are used only for importing \nvariables, but if you make your own themes you can try using them for whatever you like!\n\nAn import statement looks like the following:\n\n```\nimport \"../path/to/file.syncat\";\n```\n\nThe path is resolved relative to the path of the file that it is written in. Imports are resolved\nrecursively, but there is currently no mechanism to avoid loading an import twice, so be careful\nnot to create cycles. This will need to be fixed in future. They are also all resolved after every\nrule and declaration in the current file, so it does not really matter where you put the import\nstatements.\n\nThe variables and rules defined in an imported file are given lower priority to rules and variables\ndefined in the current file. Additionally, imports are resolved in order, so if there are conflicting \ndeclarations in two imported files, the file whose import statement appears first will take priority.\n\nIf you made a tree of all the imports, they would be resolved in a depth-first, top-to-bottom sort of\norder.\n\n## The \"Meta\" stylesheet\n\nIn addition to the `[language].syncat` files which style the source code of each language, you can\ninclude the `.syncat` file (with no name portion) to configure some of the extra features of Syncat.\n\nThere are only a few, specific selectors which are supported. Each accepts any of the regular style\noptions as above (though `language` will have no effect), and some have extra options documented\nbelow:\n\n*   `line_number`: The styling for line numbers (pass `-n` option)\n*   `line_ending`: The styling for the end of line marker (pass `-E` option)\n    *   `content: [string]`: Use the provided string as the end of line marker\n*   `margin`: The frame drawing characters, between line numbers and the code, and between the\n    files when using `-f` flags\n    *   `content: [string]`: Valid values are \"ascii\" (uses `-|+` characters) or \"unicode\" (unicode box drawing characters)\n*   `title`: The file name when drawn in the title frame (`-ff` flag)\n*   `vcs_addition`: Additions detected by Git\n    *   `content: [string]`: Use the provided string as the indicator. It is recommended to use only 1\n        character\n*   `vcs_modification`: Modifications detected by Git\n    *   `content: [string]`: Use the provided string as the indicator. It is recommended to use only 1\n        character\n*   `vcs_deletion_above`: Deletions above the current line detected by Git\n    *   `content: [string]`: Use the provided string as the indicator. It is recommended to use only 1\n        character\n*   `vcs_deletion_below`: Deletions below the current line detected by Git\n    *   `content: [string]`: Use the provided string as the indicator. It is recommended to use only 1\n        character\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoxfriends%2Fsyncat-themes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoxfriends%2Fsyncat-themes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoxfriends%2Fsyncat-themes/lists"}