docs: restructure & improve contrib docs (#1876)

* docs: restructure & improve contrib docs

* chore: rework samples code

* docs: fix capitalization & brand names

* docs: PR comments & try to standardise palette vs flavor

* docs: add sample-programs

* docs: update submission guidelines (refs: #1821)

* refactor: tidy up docs

Co-authored-by: winston <hey@winston.sh>
This commit is contained in:
Hamothy 2023-01-26 18:53:05 +00:00 committed by GitHub
parent e4ebfa468c
commit b9bbd77c7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 1189 additions and 4831 deletions

View file

@ -2,25 +2,22 @@
🎉 First off, thanks for taking the time to contribute! 🎉 🎉 First off, thanks for taking the time to contribute! 🎉
> **Note**: if you are here because you want to submit a port/learn how to port Catppuccin to a program please refer to the [documentation](https://github.com/catppuccin/catppuccin/blob/main/docs/contributing.md)
## Guidelines ## Guidelines
The following is a set of guidelines for contributing to this project. Use your best judgment, and feel free to propose changes to this document in a pull request. The following is a set of guidelines for contributing to this repository. Use your best judgment, and feel free to propose
changes to this document in a pull request.
- PRs should go to the `dev` branch. Reasons: - Use the `.editorconfig` file (located at the root of this project) on your editor to "maintain consistent coding
- If there is already stuff under development, then it's likely that a conflict may occur. styles." For instructions on how to use this file refer to [EditorConfig's website](https://editorconfig.org/).
- Releases/Deployment.
- Documentation tends not to be updated by PRs.
- Testing.
- Use the `.editorconfig` file (located at the root of this project) on your editor so as to "maintain consistent coding styles". For instructions on how to use this file refer to [EditorConfig's website](https://editorconfig.org/).
## Recommendations ## Recommendations
- Create a topic branch on your fork for your specific PR. - Create a [topic branch](git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#_topic_branch) on your fork for your
- Consider using [conventionalcommits.org's](https://www.conventionalcommits.org/en/v1.0.0/) rules for creating explicit and meaningful commit messages. specific PR.
- If it's your first time contributing to a project then read [About pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) on Github's docs. - Consider using [conventionalcommits.org](https://www.conventionalcommits.org/en/v1.0.0/)'s rules for creating explicit
and meaningful commit messages.
## License - If it's your first time contributing to a project then you should look to the
popular [first-contributions](https://github.com/firstcontributions/first-contributions) repository on GitHub. This
Any contribution will be published under the same licensing terms as the project itself. will give you hands-on experience with the features of GitHub required to make a contribution. As always, feel free to
join our [Discord](https://discord.com/invite/r6Mdz5dpFc) to ask any questions and clarify your understanding, we are
more than happy to help!

View file

@ -6,7 +6,7 @@
</h3> </h3>
<h6 align="center"> <h6 align="center">
<a href="https://github.com/catppuccin/catppuccin#-palettes">Palettes</a> <a href="https://github.com/catppuccin/catppuccin#-palette">Palette</a>
· ·
<a href="https://github.com/catppuccin/catppuccin#-ports-and-more">Ports</a> <a href="https://github.com/catppuccin/catppuccin#-ports-and-more">Ports</a>
· ·
@ -33,7 +33,7 @@
&nbsp; &nbsp;
<p align="center"> <p align="center">
Catppuccin is a community-driven pastel theme that aims to be the middle ground between low and high contrast themes. It consists of 4 soothing warm palettes with 26 eye-candy colors each, perfect for coding, designing, and much more! In addition, this repository tracks the development of the actual color palette, <a href="https://github.com/catppuccin/catppuccin/tree/main/docs"><b>the project's documentation</b></a>, organization-wide assets, resources and code samples for maintainers/developers. Catppuccin is a community-driven pastel theme that aims to be the middle ground between low and high contrast themes. It consists of 4 soothing warm flavors with 26 eye-candy colors each, perfect for coding, designing, and much more! In addition, this repository tracks the development of the actual color palette, <a href="https://github.com/catppuccin/catppuccin/tree/main/docs"><b>the project's documentation</b></a>, organization-wide assets, resources and code samples for maintainers/developers.
</p> </p>
<p align="center"> <p align="center">
@ -58,16 +58,18 @@ Join our community!
### 🧠 Design Philosophy ### 🧠 Design Philosophy
- **Colorful is better than colorless**: the colorfulness of something contributes to the distinction amongst the parts of that _something_, making it marginally easier to understand how things are structured. - **Colorful is better than colorless**: the colorfulness of something contributes to the distinction amongst the parts
of that _something_, making it marginally easier to understand how things are structured.
- **There should be balance**: not too dull, not too bright. Suitability under various light conditions is a must. - **There should be balance**: not too dull, not too bright. Suitability under various light conditions is a must.
- **Harmony is superior to dissonance**: vivacious colors must complement each other. - **Harmony is superior to dissonance**: vivacious colors must complement each other.
&nbsp; &nbsp;
### 🎨 Palettes ### 🎨 Palette
**Catppuccin** consists of 4 beautiful pastel color palettes. All the details can be found below.<br> **Catppuccin** consists of 4 beautiful pastel color palettes, named **flavors**. All the details can be found below.<br>
To make the best use of them, please refer to the [style guide](https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md). To make the best use of them, please refer to
the [style guide](https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md).
<br><img src="assets/misc/transparent.png" height="10" width="0" /> <br><img src="assets/misc/transparent.png" height="10" width="0" />
<details> <details>
@ -856,7 +858,7 @@ To make the best use of them, please refer to the [style guide](https://github.c
Catppuccin is available for various apps and in different formats. Here is a list of them: Catppuccin is available for various apps and in different formats. Here is a list of them:
<details open><summary>👾 Code Editors</summary> <details open><summary>👾 Code Editors</summary>
- [Binary Ninja](https://github.com/catppuccin/binary-ninja) - [Binary Ninja](https://github.com/catppuccin/binary-ninja)
- [Cutter](https://github.com/catppuccin/cutter) - [Cutter](https://github.com/catppuccin/cutter)
@ -880,6 +882,7 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Visual Studio](https://github.com/catppuccin/visual-studio) - [Visual Studio](https://github.com/catppuccin/visual-studio)
- [Xcode](https://github.com/catppuccin/xcode) - [Xcode](https://github.com/catppuccin/xcode)
- [Xed](https://github.com/catppuccin/xed) - [Xed](https://github.com/catppuccin/xed)
</details> </details>
<details open><summary>💭 Development</summary> <details open><summary>💭 Development</summary>
@ -891,7 +894,8 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Toolbox](https://github.com/catppuccin/toolbox) - [Toolbox](https://github.com/catppuccin/toolbox)
- [mdBook](https://github.com/catppuccin/mdBook) - [mdBook](https://github.com/catppuccin/mdBook)
- [egui](https://github.com/catppuccin/egui) - [egui](https://github.com/catppuccin/egui)
</details>
</details>
<details open><summary>🔧 System</summary> <details open><summary>🔧 System</summary>
@ -932,12 +936,14 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Waybar](https://github.com/catppuccin/waybar) - [Waybar](https://github.com/catppuccin/waybar)
- [Xresources](https://github.com/catppuccin/xresources) - [Xresources](https://github.com/catppuccin/xresources)
- [Rboard](https://github.com/catppuccin/rboard) - [Rboard](https://github.com/catppuccin/rboard)
</details> </details>
<details open><summary>🐚 Shells</summary> <details open><summary>🐚 Shells</summary>
- [Fish](https://github.com/catppuccin/fish) - [Fish](https://github.com/catppuccin/fish)
- [zsh-syntax-highlighting](https://github.com/catppuccin/zsh-syntax-highlighting) - [zsh-syntax-highlighting](https://github.com/catppuccin/zsh-syntax-highlighting)
</details> </details>
<details open><summary>🤓 Productivity</summary> <details open><summary>🤓 Productivity</summary>
@ -960,6 +966,7 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Vercel](https://github.com/catppuccin/vercel) - [Vercel](https://github.com/catppuccin/vercel)
- [Wikiwand](https://github.com/catppuccin/wikiwand) - [Wikiwand](https://github.com/catppuccin/wikiwand)
- [Zathura](https://github.com/catppuccin/zathura) - [Zathura](https://github.com/catppuccin/zathura)
</details> </details>
<details open><summary>🌈 Leisure</summary> <details open><summary>🌈 Leisure</summary>
@ -977,9 +984,10 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Spicetify](https://github.com/catppuccin/spicetify) - [Spicetify](https://github.com/catppuccin/spicetify)
- [Spotify Player](https://github.com/catppuccin/spotify-player) - [Spotify Player](https://github.com/catppuccin/spotify-player)
- [Spotify-TUI](https://github.com/catppuccin/spotify-tui) - [Spotify-TUI](https://github.com/catppuccin/spotify-tui)
- [Stable Diffusion Web Ui](https://github.com/catppuccin/Stable-Diffusion-Web-UI) - [Stable Diffusion Web UI](https://github.com/catppuccin/stable-diffusion-web-ui)
- [Steam](https://github.com/catppuccin/steam) - [Steam](https://github.com/catppuccin/steam)
- [Youtube Music](https://github.com/catppuccin/youtubemusic) - [YouTube Music](https://github.com/catppuccin/youtubemusic)
</details> </details>
<details open><summary>🖥️ Browsers</summary> <details open><summary>🖥️ Browsers</summary>
@ -988,6 +996,7 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Firefox](https://github.com/catppuccin/firefox) - [Firefox](https://github.com/catppuccin/firefox)
- [Vivaldi](https://github.com/catppuccin/vivaldi) - [Vivaldi](https://github.com/catppuccin/vivaldi)
- [qutebrowser](https://github.com/catppuccin/qutebrowser) - [qutebrowser](https://github.com/catppuccin/qutebrowser)
</details> </details>
<details open><summary>🔎 Search engines</summary> <details open><summary>🔎 Search engines</summary>
@ -995,8 +1004,9 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Brave Search](https://github.com/catppuccin/brave-search) - [Brave Search](https://github.com/catppuccin/brave-search)
- [DuckDuckGo](https://github.com/catppuccin/duckduckgo) - [DuckDuckGo](https://github.com/catppuccin/duckduckgo)
- [Whoogle](https://github.com/catppuccin/whoogle) - [Whoogle](https://github.com/catppuccin/whoogle)
- [SearxNG](https://github.com/catppuccin/searxng) - [SearXNG](https://github.com/catppuccin/searxng)
- [Startpage](https://github.com/catppuccin/startpage) - [Startpage](https://github.com/catppuccin/startpage)
</details> </details>
<details open><summary>🧩 Extensions</summary> <details open><summary>🧩 Extensions</summary>
@ -1006,6 +1016,7 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Sidebery](https://github.com/catppuccin/sidebery) - [Sidebery](https://github.com/catppuccin/sidebery)
- [Vimium](https://github.com/catppuccin/vimium) - [Vimium](https://github.com/catppuccin/vimium)
- [Nighttab](https://github.com/catppuccin/nighttab) - [Nighttab](https://github.com/catppuccin/nighttab)
</details> </details>
<details open><summary>💬 Messaging</summary> <details open><summary>💬 Messaging</summary>
@ -1020,6 +1031,7 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Revolt](https://github.com/catppuccin/revolt) - [Revolt](https://github.com/catppuccin/revolt)
- [Slack](https://github.com/catppuccin/slack) - [Slack](https://github.com/catppuccin/slack)
- [Telegram](https://github.com/catppuccin/telegram) - [Telegram](https://github.com/catppuccin/telegram)
</details> </details>
<details open><summary>📝 Note-taking</summary> <details open><summary>📝 Note-taking</summary>
@ -1028,6 +1040,7 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Joplin](https://github.com/catppuccin/joplin) - [Joplin](https://github.com/catppuccin/joplin)
- [Obsidian](https://github.com/catppuccin/obsidian) - [Obsidian](https://github.com/catppuccin/obsidian)
- [Remnote](https://github.com/catppuccin/remnote) - [Remnote](https://github.com/catppuccin/remnote)
</details> </details>
<details open><summary>🌱 Terminals</summary> <details open><summary>🌱 Terminals</summary>
@ -1059,13 +1072,14 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Xfce4 Terminal](https://github.com/catppuccin/xfce4-terminal) - [Xfce4 Terminal](https://github.com/catppuccin/xfce4-terminal)
- [Zellij](https://github.com/catppuccin/zellij) - [Zellij](https://github.com/catppuccin/zellij)
- [Zutty](https://github.com/catppuccin/zutty) - [Zutty](https://github.com/catppuccin/zutty)
</details> </details>
<details open><summary>✨ Social</summary> <details open><summary>✨ Social</summary>
- [AniList](https://github.com/catppuccin/anilist) - [AniList](https://github.com/catppuccin/anilist)
- [Elk](https://github.com/catppuccin/elk) - [Elk](https://github.com/catppuccin/elk)
- [Github Readme Stats](https://github.com/catppuccin/github-readme-stats) - [GitHub Readme Stats](https://github.com/catppuccin/github-readme-stats)
- [GitHub Readme Tech Stack](https://github.com/catppuccin/github-readme-tech-stack) - [GitHub Readme Tech Stack](https://github.com/catppuccin/github-readme-tech-stack)
- [Hacker News](https://github.com/catppuccin/hacker-news) - [Hacker News](https://github.com/catppuccin/hacker-news)
- [Infinity for Reddit](https://github.com/catppuccin/infinity) - [Infinity for Reddit](https://github.com/catppuccin/infinity)
@ -1077,6 +1091,7 @@ Catppuccin is available for various apps and in different formats. Here is a lis
- [Reddit](https://github.com/catppuccin/reddit) - [Reddit](https://github.com/catppuccin/reddit)
- [Thunderbird](https://github.com/catppuccin/thunderbird) - [Thunderbird](https://github.com/catppuccin/thunderbird)
- [YouTube](https://github.com/catppuccin/youtube) - [YouTube](https://github.com/catppuccin/youtube)
</details> </details>
&nbsp; &nbsp;
@ -1086,22 +1101,37 @@ Catppuccin is available for various apps and in different formats. Here is a lis
> **Note** <br> > **Note** <br>
> Catppuccin staff reserve the right to remove and reject showcase additions if we determine the addition to be in > Catppuccin staff reserve the right to remove and reject showcase additions if we determine the addition to be in
> violation of our [CODE OF CONDUCT](https://github.com/catppuccin/.github/blob/main/CODE_OF_CONDUCT.md). Extremely > violation of our [CODE OF CONDUCT](https://github.com/catppuccin/.github/blob/main/CODE_OF_CONDUCT.md). Extremely
> personal configurations will **not** be approved and added. > personal configurations and websites will **not** be added.
If you're making an application or tool using our palette, please let us know by adding it below! If you're making an application or tool using our palette, please let us know by adding it below!
- 🌟 [flotes.app](https://flotes.app/) - A free note-taking app enhanced with flashcard features - 🌟 [flotes.app](https://flotes.app/) - A free note-taking app enhanced with flashcard features
- 🌟 [AnuPpuccin](https://github.com/AnubisNekhet/AnuPpuccin) - Highly customisable theme for [Obsidian](https://obsidian.md/) - 🌟 [AnuPpuccin](https://github.com/AnubisNekhet/AnuPpuccin) - Highly customisable theme
- 🌟 [name] - [short description] for [Obsidian](https://obsidian.md/)
&nbsp; &nbsp;
### 👐 Contribute ### 👐 Contributing
> **Note** <br>
> if you would like to submit a port or learn how to port Catppuccin to a program, please refer to
> the [port-creation.md](https://github.com/catppuccin/catppuccin/blob/main/docs/port-creation.md).
See [CONTRIBUTING.md](https://github.com/catppuccin/catppuccin/blob/main/CONTRIBUTING.md). See [CONTRIBUTING.md](https://github.com/catppuccin/catppuccin/blob/main/CONTRIBUTING.md).
&nbsp; &nbsp;
### 🔧 Usage
If you're interested in using our palette for your own project, make sure to check
out [catppuccin/palette](https://github.com/catppuccin/palette) where you can find integrations with popular frameworks
and tools.
If you already have a project using our palette, don't forget to add it to
our [showcase](#-showcase) section above!
&nbsp;
### 📜 License ### 📜 License
Catppuccin is released under the MIT license, which grants the following permissions: Catppuccin is released under the MIT license, which grants the following permissions:

View file

@ -7,7 +7,7 @@
</p> </p>
<p align="center"> <p align="center">
Catppuccin is a community-driven pastel theme that aims to be the middle ground between low and high contrast themes. It consists of 4 soothing warms palette with 26 eye-candy colors each, perfect for coding, designing, and much more! In addition, this repository tracks the development of the actual color palette, organization-wide assets, resources and code samples for maintainers/developers. Catppuccin is a community-driven pastel theme that aims to be the middle ground between low and high contrast themes. It consists of 4 soothing warm flavors with 26 eye-candy colors each, perfect for coding, designing, and much more! In addition, this repository tracks the development of the actual color palette, organization-wide assets, resources and code samples for maintainers/developers.
</p> </p>
&nbsp; &nbsp;
@ -20,10 +20,9 @@ Catppuccin is a community-driven pastel theme that aims to be the middle ground
### 🪴 Index ### 🪴 Index
+ [Specifications](https://github.com/catppuccin/catppuccin/blob/main/docs/specs.md): properties of the palettes + [Specifications](https://github.com/catppuccin/catppuccin/blob/main/docs/specs.md): properties of the palette
+ [Integrating](https://github.com/catppuccin/catppuccin/blob/main/docs/integration.md): how to implement Catppuccin in your own projects + [Style Guide](https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md): a guide on how to properly use the palette
+ [Style Guide](https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md): a guide on how to properly use the palettes + [Port Creation](https://github.com/catppuccin/catppuccin/blob/main/docs/port-creation.md): creating Catppuccin ports
+ [Contributing](https://github.com/catppuccin/catppuccin/blob/main/docs/contributing.md): creating Catppuccin ports
&nbsp; &nbsp;

View file

@ -1,82 +0,0 @@
<p align="center">
<h2 align="center">🤝 Contributing</h2>
</p>
<p align="center">
Creating Catppuccin ports
</p>
&nbsp;
### What's a port?
A port is basically an adaptation of Catppuccin's palettes for an app to use. Think of it as a colorscheme for a program that styles every UI component it consists of!
&nbsp;
### Creation
You can create ports using [this](https://github.com/catppuccin/template) public template as a blueprint. However, you must **not** create it the traditional way (by clicking **Use this template**), because this leaves a _small_ tag under the repos' name that says `generated from <template>`. To avoid this, follow the instructions below:
1. Create the repo and leave it empty:
```
mkdir name_of_your_port
cd name_of_your_port
git init
```
2. Add this template as a remote:
```
git remote add template https://github.com/catppuccin/template.git
```
3. Pull from it:
```
git pull template main
```
4. Delete the remote:
```
git remote remove template
```
5. Make the template its own repository by running
```
git reset $(git commit-tree HEAD^{tree} -m "feat: initial commit")
```
6. Set up the rest of your port, and push it to your user repository!
&nbsp;
### Styling!
Although you just created the repo successfully, it's important to style it properly to ensure consistency:
- The name of the repo must be the simplest version of the app's name (e.g `nvim` instead of `NeoVim`). You may use hyphens if needed (e.g. `windows-files`).
- Put the images under `assets/`. If there are a bunch of them consider [creating an empty branch](https://gist.github.com/joncardasis/e6494afd538a400722545163eb2e1fa5) (e.g. `assets`) and storing them there.
- Format the repo's description as "`<emoji>` Soothing pastel theme for `<app name>`".
- `<emoji>` should be an emoji that you feel represents the app best.
- `<app name>` is the name of the app, capitalized properly.
- Add `catppuccin` to the topics.
- Ensure uppercase meta files (e.g. `README.md`)
- Don't add health files (e.g. `CODE_OF_CONDUCTS.md`, `SUPPORT.md`), those are organization-wide files stored [here](https://github.com/catppuccin/.github).
&nbsp;
### Tools
Since Catppuccin is available in 4 palettes it's understandable that it may not be quite as easy to make 4 versions of a port. So to help with that, we have built a bunch of tools to make life easier when creating Catppuccin ports. You'll find them all (with instructions) under our [catppuccin/toolbox](https://github.com/catppuccin/toolbox) repo. Particularly, for the initial problem stated, you'd want to take a look at the [Puccinier](https://github.com/catppuccin/toolbox#%EF%B8%8F-puccinier) tool.
&nbsp;
### Submission
Raise a discussion under main repository [here!](https://github.com/catppuccin/catppuccin/discussions/new?category=port-requests)
The title should be the **simplest** name of the application/tool/website in **lower-kebab-case** that you are wanting ported over.
E.g. **NeoVim** -> **neovim**
If you have already created a repository containing the work, make sure to include it within the description for others to see! Feel free to join our [Discord](https://discord.com/invite/r6Mdz5dpFc) and share it there too!
The discussion will be transferred to an issue once the [staff team](https://github.com/orgs/catppuccin/teams/staff/members)
have deemed the port ready to be reviewed and merged!

View file

@ -1,30 +0,0 @@
<p align="center">
<h2 align="center">📦 Integration</h2>
</p>
<p align="center">
How to implement Catppuccin in your own projects
</p>
&nbsp;
### How to
Catppuccin comes in many formats to cover a wide range of project types and tech stacks. Its palettes have especially been designed for UI elements and code syntax highlighting often found in projects build with web technologies like websites; hence why we have a dedicated repository for storing the various formats and presentation of the palettes: [catppuccin/palette](https://github.com/catppuccin/palette).
&nbsp;
### Web Development
Since Catppuccin is heavily used in web technology based projects, it's main installation method is therefore npm, the Node.js package manager.
Install and add it as production dependency by running `npm` from the command line:
```
npm install --save @catppuccin/palette
```
&nbsp;
### Graphical Design
Color swatches are simply a palette showing a variety of shades of the same color. Here, Catppuccin has various "swatches" in different formats to be used in software ranging from Adobe Products to graphical design apps such as Figma and InkScape. You can find them under [catppuccin/palette](https://github.com/catppuccin/palette).

96
docs/port-creation.md Normal file
View file

@ -0,0 +1,96 @@
<p align="center">
<h2 align="center">🧱 Port Creation</h2>
</p>
<p align="center">
Guidelines for submitting and creating ports
</p>
&nbsp;
### What's a port?
A port is an adaptation of Catppuccin's palette for an app to use. Think of it as a colorscheme for a program
that styles every UI component it consists of!
&nbsp;
### Submission
Raise a discussion under main
repository [here!](https://github.com/catppuccin/catppuccin/discussions/new?category=port-requests) The title should be
the **simplest** name of the application/tool/website/etc that you are wanting ported over.
If you have already created a repository containing the work, make sure to include it within the description for others
to see! Feel free to join our [Discord](https://discord.com/invite/r6Mdz5dpFc) and share it there too!
The discussion will be transferred to an issue by
the [staff team](https://github.com/orgs/catppuccin/teams/staff/members) once we have deemed the port ready to be
reviewed and merged!
All ports should conform to our [CODE OF CONDUCT](https://github.com/catppuccin/.github/blob/main/CODE_OF_CONDUCT.md)
and we, the staff team, reserve the right to choose what ports will be included under the organisation. As a
community-driven project, we want to keep a neutral environment for all users. Therefore, **we do not accept
contributions that have a religious or political context.** However, we have no issue with our palette being used in
these contexts.
&nbsp;
### Creation
You can create ports using [this](https://github.com/catppuccin/template) public template as a blueprint.
1. Clone template repository
```
git clone https://github.com/catppuccin/template.git <name_of_your_port>
```
2. Navigate into the cloned repository
```
cd <name_of_your_port>
```
3. Delete the existing remote
```
git remote remove origin
```
4. Set up the rest of your port, and push it to your user repository!
&nbsp;
### Licensing
Any contribution will be published under the same licensing terms as the project itself. However, there
are [exceptions to this rule](https://github.com/search?q=org%3Acatppuccin+-license%3Amit). Please get in touch with us
if that is the case with your work!
&nbsp;
### Styling!
After creating the repo successfully, it's important to style it properly to ensure consistency:
- The name of the repo must be the simplest version of the app's name (e.g. `nvim` instead of `NeoVim`). You may use
hyphens if needed (e.g. `windows-files`).
- Put the images under `assets/`.
- Format the repo's description as "`<emoji>` Soothing pastel theme for `<app name>`".
- `<emoji>` should be an emoji that you feel represents the app best.
- `<app name>` is the name of the app, capitalized properly.
- Add `catppuccin`, and `theme` to the topics.
- Ensure uppercase meta files (e.g. `README.md`)
- Don't add health files (e.g. `CODE_OF_CONDUCT.md`, `SUPPORT.md`), those are organization-wide files
stored [here](https://github.com/catppuccin/.github).
&nbsp;
### Tools
Since Catppuccin is available in 4 flavors it's understandable that it may be difficult to make 4 versions of a
port. So to help with that, we have built a bunch of tools to make life easier when creating Catppuccin ports. You'll
find them all (with instructions) under our [catppuccin/toolbox](https://github.com/catppuccin/toolbox) repo.
An essential tool for creating ports is [catwalk](https://github.com/catppuccin/toolbox#catwalk), this is used to create
a layered screenshot of your port which combines all four flavors into one.

View file

@ -3,20 +3,25 @@
</p> </p>
<p align="center"> <p align="center">
Properties of the palettes Properties of the palette
</p> </p>
&nbsp; &nbsp;
### Palettes ### Palette
Catppuccin consists of four named color palettes: Latte, Frappe, Macchiato, and Mocha. Each palette has its use-cases and a reason to exist! (so to speak). Every palette has labels (AKA colors) that provide different syntactic meanings and color effects for dark & bright ambiance designs. Each one of them was created aiming for a clear, uncluttered, and elegant design following a minimal and flat style pattern. Catppuccin consists of four named flavors: Latte, Frappé, Macchiato, and Mocha. Each flavor has its use-cases
and a reason to exist! (so to speak). Every flavor has labels (AKA colors) that provide different syntactic meanings
and color effects for dark & bright ambiance designs. Each one of them was created aiming for a clear, uncluttered, and
elegant design following a minimal and flat style pattern.
&nbsp; &nbsp;
### Subpalettes ### Sub-palettes
Every palette consists of two subpalettes: one monochromatic and one analogous. The Monochromatic subpalette consists of different shades of a purple-gray and a very pale lavender and is often used for UI components. Whereas the Analogous palette has every color in the rainbow and is often used for syntactic elements. Every flavor consists of two sub-palettes: one monochromatic and one analogous. The monochromatic sub-palette consists
of different shades of a purple-gray and a very pale lavender and is often used for UI components. Whereas the analogous
palette has every color in the rainbow and is often used for syntactic elements.
&nbsp; &nbsp;

View file

@ -1,3 +1,14 @@
# Coding Samples # Coding Samples
Small samples from various programming/markup/config languages to check how Catppuccin looks on them. Small samples from various programming/markup/config languages to check how Catppuccin looks on them.
## Other Sources
When you need samples from a wider set of languages, please look towards:
- [kate-editor.org/syntax](kate-editor.org/syntax)
- [TheRenegadeCoder/sample-programs](https://github.com/TheRenegadeCoder/sample-programs)
# Acknowledgement
These samples were taken from [JetBrains Intellij IDEA](https://www.jetbrains.com/idea/)'s syntax highlighting tools.

View file

@ -1,640 +1,23 @@
#!/bin/bash #!/usr/bin/env sh
#sve = System Variable Exemplifier #Sample comment
#This script executes whatever file you tell regardless of in which directory it's currently in. let "a=16 << 2";
b="Sample text";
# TO-DO function foo() {
# + on recurse_dirs2() -- make it so that any file with 'Main' on its name will get compiled at the end, cuz else it's going to cause error if [ $string1 == $string2 ]; then
# + make it so that $temp_cp can be edited using this scritpt for url in `cat example.txt`; do
# +,i remove one of the entries curl $url > result.html
# +,i add an entry done
# + fix bugs fi
# +,i if entry if removed and entry is last of entries then the entry before that one will have an collon, which is something that will cause an error to the parser }
# this is a simple test becas (done)
# + from $0 -ef a -> if "entry" is on $temp_cp then do not add entry, print message, else, add it (done)
# + edit --help str (done)
# + avoid compiling already compiled files
# +,i mkdir /tmp/2sve_tmp -- dir where "already compiled things" file is stored
# +,j touch /tmp/2sve_tmp/compiled_file_list.json
# +,i after first compile add all files compiled to list
# +,i if `stat --format "%Y" <file_name>` == `stat --format "%Y" hello.txt` of file with same name in compiled_file_list.json, then don't compile, else, do so
OUT_DICT=out rm -f $(find / -name core) &> /dev/null
temp_cp=/usr/local/bin/kt_temp_classpaths/kttemp_cp.json mkdir -p "${AGENT_USER_HOME_${PLATFORM}}"
temp_temp_cp=/usr/local/bin/kt_temp_classpaths/kttemp_temp_cp.json
#lists
dir_compiled=/tmp/2sve_tmp/
dir_sessions=/tmp/2sve_tmp/sessions/
txt_sessions=/tmp/2sve_tmp/current_sessions.txt
lines_sessions=`wc -l $txt_sessions | awk '{ print $1 }'`
testable_file=/tmp/2sve_tmp/test1.txt
hashtag="#"
#get shortened version of script's name
# this_scrpt=`basename "$0" &>/dev/null`
this_scrpt=`basename "$0"`
script_help=$( cat << EOF
This script simplifies the process of executing and compiling kolin code/projects
using simple configuration files.
Usages:
#0: ${this_scrpt} [arg] <modifier(s)?>
Arguments:
-h,--help See this help message.
-c,--compile Compile all .kt files in current dir into
current dir or a given dir a subargument. Fail: if errror on the code of given files.
-r,--run Run a .class file using 'kotlin'. Fail: if file
does not exist
-ef,--edit-file [mode: a(dd)/d(elete)] Edit the configuration file ($temp_cp) to
either add or remove an entry depinding on the mode. Fail [when adding]: if entry alredy
exists; Fail [when removing]: if out of range index is given.
-gcp|--get-class-paths Show prettily all the entries in the configuration
file ($temp_cp)
Example:
#0: $this_scrpt -c . 0
Explanation: compile all .kt files in cwd into cwd using the default classpath
multiline='first line
second line
third line'
cat << EOF
Sample text
EOF EOF
)
function create_dirs() {
for_jsons=$( cat << EOF
{
"test_key": "test_val"
}
EOF
)
in_dir=$1
compiled_list="${in_dir}compiled_list.json"
compiled_list_tmp="${in_dir}compiled_list_tmp.json"
touch $compiled_list $compiled_list_tmp
echo "$for_jsons" > $compiled_list
}
function recurse_dirs1() {
# readarray -t assArrayCP2< <(jq -r '.[]' $compiled_list)
files_array=$(find . -type f -name "*.kt") #find all files with the .kt (kotlin) exte
test_array=()
sub_str1="main"
sub_str2="Main"
c_line=1
for j in "${files_array[@]}"; do #this is because files on $files_array can't one by one
test_array+=($j)
done
if [[ $lines_sessions == 0 ]]; then
new_session="${dir_sessions}session1/"
mkdir $new_session
# append to file
echo "$out" >> $txt_sessions
create_dirs $new_session
else
while read -r line; do
# echo "current line = $c_line\ttotal lines = $lines_file"
if [[ "$line" == "$out" ]]; then
compiled_list="${dir_sessions}session$c_line/compiled_list.json"
compiled_list_tmp="${dir_sessions}session$c_line/compiled_list_tmp.json"
break
else
if [[ $c_line == $lines_sessions ]]; then
# echo "recursion limit reached"; break
new_session="${dir_sessions}session$((lines_sessions+1))/"
mkdir $new_session
# append to file
echo "$out" >> $txt_sessions
create_dirs $new_session
break
else
c_line=$((c_line+1))
fi
fi
done < $txt_sessions
fi
testarray_size=${#test_array[@]}
# echo "files array size = $testarray_size"
second_counter=0
for file in "${test_array[@]}"; do
readarray -t assArrayCP2< <(jq -r '.[]' $compiled_list)
counter=-1
for key in ${!assArrayCP2[@]}; do
counter=$((counter+1))
done
counter_plus_two=$((counter+2))
counter_plus_one=$((counter+1))
counter_plus_three=$((counter+3))
final_counter="${counter_plus_three}s"
counter=$((AACP2_size + 1))
last_entry=-1
lines_in_list=`wc -l $compiled_list | awk '{ print $1 }'`
lines_minusone="$((lines_in_list - 1))s"
tarray_size=${#test_array[@]}
tas_plus1=$((tarray_size + 1))
# echo "\tSECOND COUNTER = $second_counter"
AACP2_size=${#assArrayCP2[@]}
inner_counter=1
current_stats=`stat --format "%Y" $file`
only_name=`basename "$file"`
cmd1="cat $compiled_list | jq '.\"$only_name\"'"
# cmd1="cat $compiled_list | jq '.\"$test_name\"'"
evaluation_file=`eval $cmd1`
eval_file_without_apostrofes=${evaluation_file//\"/}
if [[ "$evaluation_file" == "null" ]]; then #file is not on the list
if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then
is_main=$file
to_change=true
second_counter=$((second_counter+1))
str_replacement="${hashtag}${counter_plus_one};${file_stats}"
cat $compiled_list | jq --arg fsts "$current_stats" '. + {"###": $fsts}' > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp
sed -i "$final_counter/"$hashtag$hashtag$hashtag"/"$only_name"/g" $compiled_list
if [[ $((testarray_size)) == 1 ]]; then
:
else
continue #this continue is causing issues but it also helps in some situations
fi
else
:
fi
echo "🍉 File = $file"
# echo "var is empty, therefore file is not added into the array"
echo -e "\tIn config status: not sited"
echo -e "\tChanged? = Null\n"
str_replacement="${hashtag}${counter_plus_one};${file_stats}"
cat $compiled_list | jq --arg fsts "$current_stats" '. + {"###": $fsts}' > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp
sed -i "$final_counter/"$hashtag$hashtag$hashtag"/"$only_name"/g" $compiled_list
#compile the file here
if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given
echo -e "\t🔰 compiling:\t$file"; `kotlinc $file -d . -cp $whichKeyCP`
echo ""
second_counter=$((second_counter+1))
else #var has something, dir was given
echo -e "\t🔰 compiling:\t$file"; `kotlinc $file -d $out -cp $whichKeyCP`
echo ""
second_counter=$((second_counter+1))
fi
if [[ $second_counter == $((testarray_size)) ]]; then
if [[ "${test_array[@]}" =~ "${is_main}" && $to_change = true ]]; then
echo "🍉 File = $is_main"
# echo "var is empty, therefore file is not added into the array"
echo -e "\tIn config status: not sited"
echo -e "\tChanged? = Null\n"
if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given
echo -e "\t🔰 compiling:\t$is_main"; `kotlinc $is_main -d . -cp $whichKeyCP`
echo ""
else
echo -e "\t🔰 compiling:\t$is_main"; `kotlinc $is_main -d $out -cp $whichKeyCP`
echo ""
fi
else
:
fi
else
:
fi
else #file is on the list
# echo "File is already on the the configuration file"
# echo -e "\tCurrent stats = $current_stats\n\tStats in config = $eval_file_without_apostrofes"
if [[ "$current_stats" == "$eval_file_without_apostrofes" ]]; then
if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then
is_main=$file
to_change=false
second_counter=$((second_counter+1))
else
:
fi
echo "🍉 File = $file"
echo -e "\tIn config status: sited"
# echo -e "\n---------File hasn't been changed---------\n" #file shouldn't be compiled
echo -e "\tChanged? = False\n"
second_counter=$((second_counter+1))
#not compile
else
if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then
is_main=$file
to_change=true
second_counter=$((second_counter+1))
cmd2="cat $compiled_list | jq --arg foo "$current_stats" '. + {\"$only_name\": \$foo}'"
final_str=`eval $cmd2`
echo "$final_str" > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp; continue
else
:
fi
echo "🍉 File = $file"
echo -e "\tIn config status: sited"
# echo -e "\n-------------File was changed--------------\n"
echo -e "\tChanged? = True\n"
#replace with new stats
cmd2="cat $compiled_list | jq --arg foo "$current_stats" '. + {\"$only_name\": \$foo}'"
final_str=`eval $cmd2`
echo "$final_str" > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp
if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given
echo -e "\t🔰 compiling:\t$file"; `kotlinc $file -d . -cp $whichKeyCP`
echo ""
second_counter=$((second_counter+1))
else #var has something, dir was given
echo -e "\t🔰 compiling:\t$file"; `kotlinc $file -d $out -cp $whichKeyCP`
echo ""
second_counter=$((second_counter+1))
fi
fi
if [[ $second_counter == $((testarray_size)) ]]; then
if [[ "${test_array[@]}" =~ "${is_main}" && $to_change = true ]]; then
echo "🍉 File = $is_main"
# echo "var is empty, therefore file is not added into the array"
echo -e "\tIn config status: not sited"
echo -e "\tChanged? = Null\n"
if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given
echo -e "\t🔰 compiling:\t$is_main"; `kotlinc $is_main -d . -cp $whichKeyCP`
else #var has something, dir was given
echo -e "\t🔰 compiling:\t$is_main"; `kotlinc $is_main -d $out -cp $whichKeyCP`
fi
else
:
fi
else
:
fi
fi
done
time_end=`date +%s`
runtime=$((time_end-time_start))
case ${?} in
0)
echo -e "\n-----------------------------------------"
echo -e "Everything was compiled successfully!"
echo -e "Time: ${runtime}secs."
;;
*)
echo -e "\n\nAn error ocurred while compiling, check '$this_scrpt -h' for help."
echo -e "Time: ${runtime}secs."
;;
esac
}
function recurse_dirs2() {
files_array=$(find . -type f -name "*.kt") #find all files with the .kt (kotlin) extension
test_array=()
for j in "${files_array[@]}"; do #this is because files on $files_array can't be accessed one by one
test_array+=($j)
done
sub_str1="main"
sub_str2="Main"
echo -e "\n\t--------Files--------\n"
#note: the emoji is for orientating the user in case the error output is huge
time_start=`date +%s`
if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given
for file in "${test_array[@]}"; do
if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then
is_main=$file
else
echo -e "🍉 compiling:\t$file"; `kotlinc $file -d . -cp $whichKeyCP`
fi
done
echo -e "🍉 compiling:\t$is_main"; `kotlinc $is_main -d . -cp $whichKeyCP`
else #var has something, dir was given
for file in "${test_array[@]}"; do
if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then
is_main="$file"
else
echo -e "🍉 compiling:\t$file"; `kotlinc $file -d $out -cp $whichKeyCP`
fi
done
echo -e "🍉 compiling:\t$is_main"; `kotlinc $is_main -d $out -cp $whichKeyCP`
fi
time_end=`date +%s`
runtime=$((time_end-time_start))
case ${?} in
0)
echo -e "\n\nEverything was compiled successfully!"
echo -e "Time: ${runtime}secs."
;;
*)
echo -e "\n\nAn error ocurred while compiling, check '$this_scrpt -h' for help."
echo -e "Time: ${runtime}secs."
;;
esac
}
function get_class_paths() {
readarray -t assArrayCP< <(jq -r '.[]' $temp_cp)
echo -e "This are the available classpaths: \n"
echo -e "--------------------------CLASSPATHS--------------------------"
for key in ${!assArrayCP[@]}; do
echo -e " 💡$key -> ${assArrayCP[$key]}"
done
echo -e "--------------------------CLASSPATHS--------------------------"
}
function check_trailing_comma() {
`sed -i.bak ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' $temp_cp` #remove trailing comma if any
}
function test_func() {
for file in *; do
if [[ "$file" == "$0" ]]; then
echo "found"
else
continue
fi
done
}
if [[ -n "$1" ]]; then
case "$1" in
-h|--help)
echo "$script_help"
exit 0
;;
-c|--compile) #$1 = "-c"
out=$2
whichKeyCP=$3
if [[ -z "$out" ]]; then
out=`pwd`
else
:
fi
# echo "1 = $1; 2 = $2; 3 = $3"
# echo -e "\n\nout= $out; whichKeyCP= $whichKeyCP"
readarray -t assArrayCP< <(jq -r '.[]' $temp_cp)
AACP_size=${#assArrayCP[@]}
if [[ -z "$3" ]]; then #var is empty
echo "this ran"
whichKeyCP=0
else
counter=1
for key in ${!assArrayCP[@]}; do
# echo "key = $key"
if [[ "$key" == "$whichKeyCP" ]]; then
# echo -e " 💡$key -> ${assArrayCP[$key]}"
whichKeyCP=${assArrayCP[$key]}; break
else
if [[ $AACP_size == $counter ]]; then
echo -e "\nERROR: Unfortunately the key '$whichKeyCP' was not found on the config file.\nFor more information run '$this_scrpt --get-class-paths' or '$this_scrpt -gcp'"
whichKeyCP=0
exit 1
else
:
fi
fi
counter=$((counter+1))
done
fi
# echo -e "which key = $whichKeyCP"
echo -e "\nCLASSPATH:\t$whichKeyCP\nOUT DIR:\t$out\n"
recurse_dirs2
exit 0
;;
-sc|--smart-compile)
if [[ -f "$compiled_list" ]]; then #exists
:
else #does not exist
# mkdir -p $dir_compiled && touch $compiled_list $compiled_list_tmp
# `echo '{ "test_file":"test_stats" }' | jq . > $compiled_list`
mkdir -p $dir_compiled $dir_sessions && touch $txt_sessions
lines_sessions=`wc -l $txt_sessions | awk '{ print $1 }'`
fi
#--------Status of a file---------#
#In config staus: [sited|not sited]
#Change? = [Null|True|False]
#
#for config statuses:
# sited: the program already has a register of that given file in the configurationg files
# not sited: the program does not has a register of that given file in the configurationg files
#for changed:
# Null: for files that are yet to be registered in the archive
# True: Files' current stats and in-config stats are different, therefore file is considered to have changed
# +,i what is considered as changed?
# +,j if file was directly written
# +,j if a program saved the file (regardless of having edited something). E.g. when writing with vim (:w)
# False: File' current stats and in-config stats are the same, therefore file has not changed
out=$2
whichKeyCP=$3
time_start=`date +%s`
# echo "1 = $1; 2 = $2; 3 = $3"
# echo -e "\n\nout= $out; whichKeyCP= $whichKeyCP"
readarray -t assArrayCP< <(jq -r '.[]' $temp_cp)
AACP_size=${#assArrayCP[@]}
if [[ -z "$3" ]]; then #var is empty
echo "this ran"
whichKeyCP=0
else
counter=1
for key in ${!assArrayCP[@]}; do
# echo "key = $key"
if [[ "$key" == "$whichKeyCP" ]]; then
# echo -e " 💡$key -> ${assArrayCP[$key]}"
whichKeyCP=${assArrayCP[$key]}; break
else
if [[ $AACP_size == $counter ]]; then
echo -e "\nERROR: Unfortunately the key '$whichKeyCP' was not found on the config file.\nFor more information run '$this_scrpt --get-class-paths' or '$this_scrpt -gcp'"
whichKeyCP=0
exit 1
else
:
fi
fi
counter=$((counter+1))
done
fi
echo -e "\nCLASSPATH:\t$whichKeyCP\nOUT DIR:\t$out\n"
recurse_dirs1
exit 0
;;
-gcp|--get-class-paths)
get_class_paths
echo -e "\nNote: you can add/remove more if you want by accessing the configuration file or using\n\t'$this_scrpt --edit-file --add' #for adding a new entry\n\t'$this_scrpt --edit-file --delete' #for deleting entries\nThe configuration file is located at: $temp_cp\n"
exit 0
;;
-ef|--edit-file)
mode=$2
get_class_paths; echo ""
AACP_size=${#assArrayCP[@]}
if [ "$mode" == "d" ] || [ "$mode" == "-d" ] || [ "$mode" == "delete" ] || [ "$mode" == "--delete" ]; then #delete mode
read -p "Which of the aforeshown entries do you want to remove [0-$((AACP_size-1))]?: " entry_to_remove
if (($entry_to_remove >= 0 && $entry_to_remove <= $((AACP_size-1)))); then
counter=1
for key in ${!assArrayCP[@]}; do
# echo -e " 💡$key -> ${assArrayCP[$key]}"
if [[ $key == $entry_to_remove ]]; then
#entry was found
entry="${assArrayCP[$key]}"
# match=`grep -n "$entry" $temp_cp &>/dev/null` #will supress output as well as error messages
match=`grep -n "$entry" $temp_cp` #will supress output as well as error messages
line_number=$(echo "$match" | cut -c1-1) #gets just the line number of the $match
line_wd="${line_number}d"
echo -e "\tentry = $entry\n\tmatch = $match\n\tline_number = $line_number\n\tline_wd = $line_wdn\n\tcounter = $counter" #show info
read -t 10 -n 1 -s -r -p "Press any key to continue (you have 10 seconds)..." #ask for authorization
`sed -i $line_wd $temp_cp` #delete the line
case ${?} in
0)
echo -e "\n\n-----------------------------------------"
echo -e "Entry removed successfully"
;;
*)
echo -e "\n\nAn error ocurred while removing the entry, check '$this_scrpt -h' for help."
;;
esac
# `sed -i.bak ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' $temp_cp` #remove trailing comma if any #mn: was replaced by a function
check_trailing_comma
echo ""
break;
else
if [[ $AACP_size == $counter ]]; then
echo -e "\nERROR: Unfortunately the key '$entry_to_remove' was not found on the config file.\nFor more information run '$this_scrpt --get-class-paths' or '$this_scrpt -gcp'"
exit 1
else
:
fi
fi
counter=$((counter+1))
done
else
echo -e "\nThe number $entry_to_remove is out of range, remember it must be between 0 and $((AACP_size-1)) (according to the options above)"
fi
elif [ "$mode" == "a" ] || [ "$mode" == "-a" ] ||[ "$mode" == "add" ] || [ "$mode" == "--add" ]; then #append mode
read -p "Type or paste the directories' path here: " entry_to_add
for key in ${!assArrayCP[@]}; do
if [[ "$entry_to_add" == "${assArrayCP[$key]}" ]]; then
echo -e "Sorry, your desired entry ($entry_to_add) is already on the configuration (.json) file.\nIf you think this is a mistake you can run '$this_scrpt -ef --delete' to remove the 'problematic' entry".
exit 1
else
: # do nothing
fi
done
readarray -t assArrayCP< <(jq -r '.[]' $temp_cp)
AACP_size=${#assArrayCP[@]}
counter=-1
for key in ${!assArrayCP[@]}; do
# echo -e " 💡$key -> ${assArrayCP[$key]}"
counter=$((counter+1))
done
counter_plus_three=$((counter+3))
counter_plus_two=$((counter+2))
counter_plus_one=$((counter+1))
final_counter="${counter_plus_three}s"
read -t 10 -n 1 -s -r -p "Press any key to continue (you have 10 seconds)..." #ask for authorization
echo "\n"
cat $temp_cp | jq --arg classpath "$entry_to_add" '. + {"classpath#": $classpath}' > $temp_temp_cp && cat $temp_temp_cp > $temp_cp; echo "" > $temp_temp_cp
sed -i "$final_counter/"$hashtag"/"$hashtag$counter_plus_one"/g" $temp_cp
case ${?} in
0)
echo -e "\n-----------------------------------------"
echo -e "Entry added successfully"
;;
*)
echo -e "\n\nAn error ocurred while adding the entry, check '$this_scrpt -h' for help."
;;
esac
check_trailing_comma
else
:
fi
exit 0
;;
-r|--run)
file=$2
final_file=${file/".class"/}
kotlin $final_file
exit
;;
*)
i=0
file=$1
#echo "arg 1 = $1" #works
#it will try to find out/ 18 times, this so as to avoid overloading the ram
#trying to find an unexistent out/. Of course this number can be increased
while [[ $i -le 18 ]]; do
if [[ -d "$OUT_DICT" ]]; then #out found
cd $OUT_DICT
kotlin $file
break
else #out not found
cd ..
i=$((i+1))
fi
done
exit 0
;;
esac
shift
else
echo -e "This script needs at least one argument to work.\nType '$this_scrpt -h' or '$this_scrpt --help' for help "
fi

View file

@ -1,71 +0,0 @@
document.addEventListener("DOMContentLoaded", () =>
document.querySelectorAll("pre.msh .js-copy").forEach((copy) =>
copy.addEventListener("click", (e) =>
e.preventDefault()
content = copy.nextElementSibling
range = document.createRange()
range.selectNode(content)
window.getSelection().addRange(range)
try
successful = document.execCommand("copy")
copy.innerHTML = "Copied!"
setTimeout =>
copy.innerHTML = "Copy"
, 1500
msg = successful ? "successful" : "unsuccessful"
console.log({ msg })
catch error
console.log("Oops, unable to copy...")
window.getSelection().removeAllRanges()
)
)
document.querySelectorAll("pre.msh code[data-language='html'] span.line").forEach((line) =>
content = line.innerHTML
content = content.replaceAll(/(&lt;(\/?))(.+?(?=&gt;))(&gt;)/g, "$1<span class='c2'>$3</span>$4")
line.innerHTML = content
pink = line.querySelector(".c2")
if pink != null
content = pink.innerHTML.split(" ")
content = content.map((part, index) =>
if index > 0
if part.includes("=")
part = part.replaceAll(/(.+?)(".*)/g, "<span class='c3'>$1</span><span class='c4'>$2</span>")
else
part = part.replaceAll(/(.*\S)/g, "<span class='c3'>$1</span>")
part
).join(" ")
pink.innerHTML = content
return
)
document.querySelectorAll("pre.msh code[data-language='css'] span.line").forEach((line) =>
content = line.innerHTML
if line.dataset.indent
content = content.split(/:/g).map((part, index) =>
if index == 0
part.replace(/(.*)/g, "<span class='c7'>$1</span>")
else
part = part.replaceAll(/(\S.+?(?=\s|;))/g, "<span class='c6'>$1</span>")
part = part.replaceAll(/(".+?(?=,|\s|;))/g, "<span class='c4'>$1</span>")
part = part.replaceAll(/(url\(.+?(?=\s|;))/g, "<span class='c3'>$1</span>")
part.replaceAll(/\((.+?(?=\)))/g, "(<span class='c4'>$1</span>")
).join(":")
else
content = content.replaceAll(/(.+?(?=,|\s|{}))/g, "<span class='c2'>$1</span>")
content = content.replaceAll(/((\.|:).+?(?=\s))/g, "<span class='c3'>$1</span>")
line.innerHTML = content
return
)
)

View file

@ -0,0 +1,52 @@
###
Some tests
###
class Animal
constructor: (@name) ->
move: (meters) -> alert @name + " moved " + meters + "m."
class Snake extends Animal
move: ->
alert 'Slithering...'
super 5
number = 42; opposite = true
/^a\/\\[a-z/\n]\u00A3b$/.test 'a//b'
square = (x) -> x * x
range = [1..2]
list = [1...5]
math =
root: Math.sqrt
cube: (x) => x * square x
race = (winner, runners...) ->
print winner, runners
alert "I knew it!" if elvis?
cubes = math.cube num for num in list
text = """
Result
is #{ @number }"""
html = ''' <body></body>'''
String::dasherize = ->
this.replace /_/g, "-"
SINGERS = {Jagger: "Rock", Elvis: "Roll"}
t = ///
[a-z]
///
$('.shopping_cart').bind 'click', (event) =>
@customer.purchase @cart
hi = `function() {
return [document.title, "Hello JavaScript"].join(": ");
}`

View file

@ -1,110 +0,0 @@
# Howdy's config file: https://github.com/boltgolt/howdy/blob/beta/howdy/src/config.ini
# Press CTRL + X to save in the nano editor
[core]
# Print that face detection is being attempted
detection_notice = false
# Print that face detection has timed out
timeout_notice = true
# Do not print anything when a face verification succeeds
no_confirmation = false
# When a user without a known face model tries to use this script, don't
# show an error but fail silently
suppress_unknown = false
# Disable Howdy in remote shells
abort_if_ssh = true
# Disable Howdy if lid is closed
abort_if_lid_closed = true
# Disable howdy in the PAM
# The howdy command will still function
disabled = false
# Use CNN instead of HOG
# CNN model is much more accurate than the HOG based model, but takes much more
# computational power to run, and is meant to be executed on a GPU to attain reasonable speed.
use_cnn = false
[video]
# The certainty of the detected face belonging to the user of the account
# On a scale from 1 to 10, values above 5 are not recommended
# Lower is better
certainty = 3.5
# The number of seconds to search before timing out
timeout = 4
# The path of the device to capture frames from
# Should be set automatically by an installer if your distro has one
device_path = none
# Print a warning if the the video device is not found
warn_no_device = true
# Scale down the video feed to this maximum height
# Speeds up face recognition but can make it less precise
max_height = 320
# Set the camera input profile to this width and height
# The largest profile will be used if set to -1
# Automatically ignored if not a valid profile
frame_width = -1
frame_height = -1
# Because of flashing IR emitters, some frames can be completely unlit
# Skip the frame if the lowest 1/8 of the histogram is above this percentage
# of the total
# The lower this setting is, the more dark frames are ignored
dark_threshold = 50
# The recorder to use. Can be either opencv (default), ffmpeg or pyv4l2.
# Switching from the default opencv to ffmpeg can help with grayscale issues.
recording_plugin = opencv
# Video format used by ffmpeg. Options include vfwcap or v4l2.
# FFMPEG only.
device_format = v4l2
# Force the use of Motion JPEG when decoding frames, fixes issues with YUYV
# raw frame decoding.
# OPENCV only.
force_mjpeg = false
# Specify exposure value explicitly. This disables autoexposure.
# Use qv4l2 to determine an appropriate value.
# OPENCV only.
exposure = -1
[snapshots]
# Capture snapshots of failed login attempts and save them to disk with metadata
# Snapshots are saved to the "snapshots" folder
save_failed = false
# Do the same as the option above but for successful attempts
save_successful = false
[rubberstamps]
# Enable specific extra checks after the user has been recognised
enabled = false
# What type of stamps to run and with what options. The type, timeout and
# failure mode are required. One line per stamp. Rule syntax:
# stamptype timeout (failsafe | faildeadly) [extra_argument=value]
stamp_rules =
nod 5s failsafe min_distance=12
[debug]
# Show a short but detailed diagnostic report in console
# Enabling this can cause some UI apps to fail, only enable it to debug
end_report = false
# More verbose logging from the rubberstamps system
verbose_stamps = false
# Pass output of the GTK auth window to the terminal
gtk_stdout = false

File diff suppressed because it is too large Load diff

View file

@ -1,183 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace PathCreation.Utility {
public static class MathUtility {
float4 frag (v2f i) : SV_Target {
float2 uv = pointOnSphereToUV(i.pos);
float2 countryData = text2D(countryData, UV).rg;
float countryOutLine = countryData[0];
int countryIndex = (int)countryData[1] - 1;
float3 colour = countryOutline;
if (countryIndex >= 0) {
float lastVisited = CountryLastVisitTime[countryIndex];
float timeSinceVisit = currentTime - lastVisitTime;
}
}
// Transform point from local to world space
public static Vector3 TransformPoint (Vector3 p, Transform t, PathSpace space) {
// path only works correctly for uniform scales, so average out xyz global scale
float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
Vector3 constrainedPos = t.position;
Quaternion constrainedRot = t.rotation;
ConstrainPosRot (ref constrainedPos, ref constrainedRot, space);
return constrainedRot * p * scale + constrainedPos;
}
// Transform point from world to local space
public static Vector3 InverseTransformPoint (Vector3 p, Transform t, PathSpace space) {
Vector3 constrainedPos = t.position;
Quaternion constrainedRot = t.rotation;
ConstrainPosRot (ref constrainedPos, ref constrainedRot, space);
// path only works correctly for uniform scales, so average out xyz global scale
float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
var offset = p - constrainedPos;
return Quaternion.Inverse (constrainedRot) * offset / scale;
}
// Transform vector from local to world space (affected by rotation and scale, but not position)
public static Vector3 TransformVector (Vector3 p, Transform t, PathSpace space) {
// path only works correctly for uniform scales, so average out xyz global scale
float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
Quaternion constrainedRot = t.rotation;
ConstrainRot (ref constrainedRot, space);
return constrainedRot * p * scale;
}
// Transform vector from world to local space (affected by rotation and scale, but not position)
public static Vector3 InverseTransformVector (Vector3 p, Transform t, PathSpace space) {
Quaternion constrainedRot = t.rotation;
ConstrainRot (ref constrainedRot, space);
// path only works correctly for uniform scales, so average out xyz global scale
float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
return Quaternion.Inverse (constrainedRot) * p / scale;
}
// Transform vector from local to world space (affected by rotation, but not position or scale)
public static Vector3 TransformDirection (Vector3 p, Transform t, PathSpace space) {
Quaternion constrainedRot = t.rotation;
ConstrainRot (ref constrainedRot, space);
return constrainedRot * p;
}
// Transform vector from world to local space (affected by rotation, but not position or scale)
public static Vector3 InverseTransformDirection (Vector3 p, Transform t, PathSpace space) {
Quaternion constrainedRot = t.rotation;
ConstrainRot (ref constrainedRot, space);
return Quaternion.Inverse (constrainedRot) * p;
}
public static bool LineSegmentsIntersect (Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2) {
float d = (b2.x - b1.x) * (a1.y - a2.y) - (a1.x - a2.x) * (b2.y - b1.y);
if (d == 0)
return false;
float t = ((b1.y - b2.y) * (a1.x - b1.x) + (b2.x - b1.x) * (a1.y - b1.y)) / d;
float u = ((a1.y - a2.y) * (a1.x - b1.x) + (a2.x - a1.x) * (a1.y - b1.y)) / d;
return t >= 0 && t <= 1 && u >= 0 && u <= 1;
}
public static bool LinesIntersect (Vector2 a1, Vector2 a2, Vector2 a3, Vector2 a4) {
return (a1.x - a2.x) * (a3.y - a4.y) - (a1.y - a2.y) * (a3.x - a4.x) != 0;
}
public static Vector2 PointOfLineLineIntersection (Vector2 a1, Vector2 a2, Vector2 a3, Vector2 a4) {
float d = (a1.x - a2.x) * (a3.y - a4.y) - (a1.y - a2.y) * (a3.x - a4.x);
if (d == 0) {
Debug.LogError ("Lines are parallel, please check that this is not the case before calling line intersection method");
return Vector2.zero;
} else {
float n = (a1.x - a3.x) * (a3.y - a4.y) - (a1.y - a3.y) * (a3.x - a4.x);
float t = n / d;
return a1 + (a2 - a1) * t;
}
}
public static Vector2 ClosestPointOnLineSegment (Vector2 p, Vector2 a, Vector2 b) {
Vector2 aB = b - a;
Vector2 aP = p - a;
float sqrLenAB = aB.sqrMagnitude;
if (sqrLenAB == 0)
return a;
float t = Mathf.Clamp01 (Vector2.Dot (aP, aB) / sqrLenAB);
return a + aB * t;
}
public static Vector3 ClosestPointOnLineSegment (Vector3 p, Vector3 a, Vector3 b) {
Vector3 aB = b - a;
Vector3 aP = p - a;
float sqrLenAB = aB.sqrMagnitude;
if (sqrLenAB == 0)
return a;
float t = Mathf.Clamp01 (Vector3.Dot (aP, aB) / sqrLenAB);
return a + aB * t;
}
public static int SideOfLine (Vector2 a, Vector2 b, Vector2 c) {
return (int) Mathf.Sign ((c.x - a.x) * (-b.y + a.y) + (c.y - a.y) * (b.x - a.x));
}
/// returns the smallest angle between ABC. Never greater than 180
public static float MinAngle (Vector3 a, Vector3 b, Vector3 c) {
return Vector3.Angle ((a - b), (c - b));
}
public static bool PointInTriangle (Vector2 a, Vector2 b, Vector2 c, Vector2 p) {
float area = 0.5f * (-b.y * c.x + a.y * (-b.x + c.x) + a.x * (b.y - c.y) + b.x * c.y);
float s = 1 / (2 * area) * (a.y * c.x - a.x * c.y + (c.y - a.y) * p.x + (a.x - c.x) * p.y);
float t = 1 / (2 * area) * (a.x * b.y - a.y * b.x + (a.y - b.y) * p.x + (b.x - a.x) * p.y);
return s >= 0 && t >= 0 && (s + t) <= 1;
}
public static bool PointsAreClockwise (Vector2[] points) {
float signedArea = 0;
for (int i = 0; i < points.Length; i++) {
int nextIndex = (i + 1) % points.Length;
signedArea += (points[nextIndex].x - points[i].x) * (points[nextIndex].y + points[i].y);
}
return signedArea >= 0;
}
static void ConstrainPosRot (ref Vector3 pos, ref Quaternion rot, PathSpace space) {
if (space == PathSpace.xy) {
var eulerAngles = rot.eulerAngles;
if (eulerAngles.x != 0 || eulerAngles.y != 0) {
rot = Quaternion.AngleAxis (eulerAngles.z, Vector3.forward);
}
pos = new Vector3 (pos.x, pos.y, 0);
} else if (space == PathSpace.xz) {
var eulerAngles = rot.eulerAngles;
if (eulerAngles.x != 0 || eulerAngles.z != 0) {
rot = Quaternion.AngleAxis (eulerAngles.y, Vector3.up);
}
pos = new Vector3 (pos.x, 0, pos.z);
}
}
static void ConstrainRot (ref Quaternion rot, PathSpace space) {
if (space == PathSpace.xy) {
var eulerAngles = rot.eulerAngles;
if (eulerAngles.x != 0 || eulerAngles.y != 0) {
rot = Quaternion.AngleAxis (eulerAngles.z, Vector3.forward);
}
} else if (space == PathSpace.xz) {
var eulerAngles = rot.eulerAngles;
if (eulerAngles.x != 0 || eulerAngles.z != 0) {
rot = Quaternion.AngleAxis (eulerAngles.y, Vector3.up);
}
}
}
}
}

View file

@ -1,175 +1,25 @@
body { @import "manual.css";
background-color: #111921;
}
.center {
display: block;
margin-left: auto;
margin-right: auto;
width: 50%;
}
@font-face { @font-face {
font-family: 'Galada-Regular'; font-family: DroidSans;
src: url('Galada-Regular.ttf'); src: url(DroidSans.ttf);
unicode-range: U+000-5FF, U+1e00-1fff, U+2000-2300;
} }
@font-face { h1.mystyle:lang(en) {
font-family: 'Overpass'; color: blue; /* TODO: change THIS to yellow for next version! */
font-style: normal; border: rgb(255, 0, 0);
font-weight: 400; background-color: #FAFAFA;
font-display: swap; background: url(hello.jpg) !important;
src: url(https://fonts.gstatic.com/s/overpass/v5/qFdH35WCmI96Ajtm81GrU9vyww.woff2)
format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Overpass';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/overpass/v5/qFdH35WCmI96Ajtm81GlU9s.woff2)
format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
U+2215, U+FEFF, U+FFFD;
} }
@import url(https://fonts.googleapis.com/css?family=Roboto:400, 300); div > p, p ~ ul, input [type="radio"] {
color: green;
* { width: 80%;
box-sizing: border-box;
} }
h1 { #header:after {
font-family: 'Galada-Regular'; color: red;
/* color: #000000; */
font-size: 90px;
text-align: center;
color: whitesmoke;
} }
h2 { &!
font-family: 'Courier';
font-size: 30px;
font-style: italic;
}
h3 {
font-family: 'Courier New', Courier, monospace;
color: #000000;
font-size: 30px;
text-align: left;
}
h5 {
font-family: 'Courier New', Courier, monospace;
font-size: 25px;
text-align: center;
color: whitesmoke;
}
#about {
color: blue;
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande',
'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
}
/* Add a black background color to the top navigation */
.topnav {
background-color: #333;
overflow: hidden;
}
/* Style the links inside the navigation bar */
.topnav a {
float: left;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
/* Change the color of links on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
/* Add a color to the active/current link */
.topnav a.active {
background-color: #04aa6d;
color: white;
}
.card {
background-color: #fff;
border-radius: 4px;
max-width: 1291px;
margin: 10% auto;
height: 301px;
position: relative;
padding: 34px;
color: #444;
cursor: pointer;
&:before {
content: '';
display: block;
position: absolute;
background-color: #ccc;
left: 20px;
right: 20px;
bottom: 0;
top: 50%;
z-index: -1;
box-shadow: 0 0 40px lighten(#000, 60%);
transition: box-shadow 0.2s ease-in-out;
}
&.level-3 {
&:hover {
&:before {
box-shadow: 0 0 80px lighten(#000, 60%);
}
}
}
}
/* The sidebar menu */
.sidenav {
height: 100%; /* Full-height: remove this if you want "auto" height */
width: 160px; /* Set the width of the sidebar */
position: fixed; /* Fixed Sidebar (stay in place on scroll) */
z-index: 1; /* Stay on top */
top: 0; /* Stay at the top */
left: 0;
background-color: #111; /* Black */
overflow-x: hidden; /* Disable horizontal scroll */
padding-top: 20px;
}
/* The navigation menu links */
.sidenav a {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
}
/* When you mouse over the navigation links, change their color */
.sidenav a:hover {
color: #f1f1f1;
}
/* On smaller screens, where height is less than 450px, change the style of the sidebar (less padding and a smaller font size) */
@media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
}

View file

@ -1,32 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Roboto:400);
@import url("chrome://communicator/skin/");
@import 'custom.css' screen and (max-width: 768px);
@font-face {
font-family: 'Galada-Regular';
src: url('Galada-Regular.ttf');
font-style: normal;
font-weight: 400;
}
/* Applies to the entire body of the HTML document (except where overridden by more specific
selectors). */
body {
margin: 25px;
background-color: rgb(240,240,240);
font-family: arial, sans-serif;
font-size: 14px;
}
/* Applies to all <h1>...</h1> elements. */
h1 {
font-size: 35px;
font-weight: normal;
margin-top: 5px;
}
/* Applies to all elements with <... class="someclass"> specified. */
.someclass { color: red; }
/* Applies to the element with <... id="someid"> specified. */
#someid { color: green; }

161
samples/go.go Normal file
View file

@ -0,0 +1,161 @@
/*
* Go highlight sample
*/
//go:build (linux || windows) && arm
// +build linux,arm windows,arm
// Package main
package main
import "fmt"
import alias "fmt"
//go:generate go tool yacc -o gopher.go -p parser gopher.y
/*
Semantic highlighting:
Generated spectrum to pick colors for local variables and parameters:
Color#1 SC1.1 SC1.2 SC1.3 SC1.4 Color#2 SC2.1 SC2.2 SC2.3 SC2.4 Color#3
Color#3 SC3.1 SC3.2 SC3.3 SC3.4 Color#4 SC4.1 SC4.2 SC4.3 SC4.4 Color#5
*/
type (
PublicInterface interface {
PublicFunc() int
privateFunc() int
}
privateInterface interface {
PublicFunc() int
privateFunc() int
}
PublicStruct struct {
PublicField int
privateField int
}
privateStruct struct {
PublicField int
privateField int
}
demoInt int
T struct {
FirstName string `json:"first_name" arbitrary text`
}
)
const (
PublicConst = 1
privateConst = 2
)
var (
PublicVar = 1
privateVar = 2
)
// PublicFunc does the thing
func PublicFunc() int {
localVar := PublicVar
return localVar
}
// privateFunc does the thing
func privateFunc() (int, int) {
LocalVar := privateVar
return LocalVar, PublicVar
}
func (ps PublicStruct) PublicFunc() int {
return ps.privateField
}
func (ps privateStruct) privateFunc() int {
return ps.PublicField
}
func _(pi PublicInterface) {
}
func _(pi privateInterface) {
}
func variableFunc(demo1 int, demo2 demoInt) {
demo1 = 3
a := PublicStruct{}
a.PublicFunc()
b := privateStruct{}
b.privateFunc()
demo2 = 4
if demo1, demo2 := privateFunc(); demo1 != 3 {
_ = demo1
_ = demo2
return
}
demoLabel:
for demo1 := range []int{1, 2, 3, 4} {
_ = demo1
continue demoLabel
}
switch {
case 1 == 2:
demo1, demo2 := privateFunc()
_ = demo1
_ = demo2
default:
_ = demo1
}
f := func() int {
return 1
}
f()
PublicFunc()
variableFunc(1, 2)
_ = demo1
_ = demo2
println("builtin function")
}
func main() {
const LocalConst = 1
const localConst = 2
fmt.Println("demo\n\xA")
alias.Println("demo")
variableFunc(1, 2)
var d, c *int = nil, nil
_, _ = c, d
_, _ = true, false
}
var ExportedVariableFunction = func() {}
var packageLocalVariableFunction = func() {}
type typeWithCall struct {
PublicFieldCall func()
privateFieldCall func()
}
func calls(t typeWithCall) {
var localVariableFunction = func() {}
ExportedVariableFunction()
packageLocalVariableFunction()
localVariableFunction()
t.PublicFieldCall()
t.privateFieldCall()
}
func _() {
var err error
a, err := 1, nil
println(a, err)
for a := 0; a < 10; a++ {
println(a)
}
}

16
samples/haskell.hs Normal file
View file

@ -0,0 +1,16 @@
{-# LANGUAGE CPP #-}
module ModuleName
import qualified ImportModuleName
"string literal"
'c'
intPair :: (Int, Int)
intPair = (456,434)
-- line comment
{- nested
comment -}
data Bool = True | False
let l1 = [1, 2]
let l2 = 1 : []
let two = 1 + 1
let f = \_ + 1
[t|select * from foo|]

View file

@ -1,131 +0,0 @@
/* See LICENSE file for copyright and license details. */
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#5F6587";
static const char col_gray2[] = "#8289AA";
static const char col_gray3[] = "#A6AFD2";
static const char col_gray4[] = "#C5CFF5";
static const char col_teal[] = "#78DCCC";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_teal, col_teal },
};
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
static const int ruleperiod = 5; /* number of seconds before rules are ignored */
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
static const LayoutMonitorRule lm_rules[] = {
/* >=w, >=h, req'd layout, new nmaster, new mfact */
{ 3000, 0, 0, 2, 0.66 },
};
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
{ "TTT", bstack },
{ "===", bstackhoriz },
};
/* key definitions */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
{ KeyPress, MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ KeyPress, MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ KeyPress, MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ KeyPress, MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_teal, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "st", NULL };
#include "movestack.c"
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
{ MODKEY|ShiftMask, XK_x, killunsel, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_u, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_o, setlayout, {.v = &layouts[4]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
{ MODKEY|ControlMask, XK_comma, tagallmon, {.i = -1 } },
{ MODKEY|ControlMask, XK_period, tagallmon, {.i = +1 } },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ KeyPress, MODKEY|ShiftMask, XK_q, quit, {0} },
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};

View file

@ -1,41 +1,15 @@
<!DOCTYPE html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html lang="en"> <!--
<head> * Sample comment
<meta charset="UTF-8" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1" /> <HTML>
<link href="css/style.css" rel="stylesheet" /> <head>
<title>GNU/Linux Doc</title> <title>IntelliJ IDEA</title>
</head>
<div class="topnav"> <body>
<a class="active" href="#home">Home</a> <h1>IntelliJ IDEA</h1>
<a href="#news">News</a> <p><br><b><IMG border=0 height=12 src="images/hg.gif" width=18 >
<a href="#contact">Contact</a> What is IntelliJ&nbsp;IDEA? &#x00B7; &Alpha; </b><br><br>
<a href="#about">About</a> <custom-tag>hello</custom_tag>
</div> </body>
<h1>
GNU/Linux
</h1>
<h5>
Posted on Wednesday, 12 May 2021
</h5>
</head>
<body>
<!-- Page content -->
<div class="card level-3">
<h2>
"<b>GNU/Linux</b> and the family of operating systems made from the GNU
system, developed by the same project, introduced the Linux
kernel. It is one of the most well-known examples of free
software and open source <em>software</em>: according to proprietary
operating systems such as Windows and Mac OS, all source code is
available to the public and the world can freely use, change and
redistribute."
</h2>
</div>
<img src="https://www.nicepng.com/png/full/201-2015470_gnu-tux-gnu-linux-logo-png.png" alt="GNU/Linux" class="center">
</body>
</html> </html>

View file

@ -1,77 +1,66 @@
package project1.ui; /* Block comment */
import static project1.umethods.SleepTime.*; import java.util.Date;
import static project1.umethods.ScreenManipulation.*;
import java.util.Scanner; import static AnInterface.CONSTANT;
import project1.ui.PatientMenu; import static java.util.Date.parse;
import project1.ui.DoctorMenu; import static SomeClass.staticField;
import project1.ui.authentication.AuthenticationMenu;
enum Months { //"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE,
JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
}
/** /**
* UIMenu * Doc comment here for <code>SomeClass</code>
*
* @param T type parameter
* @see Math#sin(double)
*/ */
public class UIMenu { @Annotation(name = value)
public class SomeClass<T extends Runnable> { // some comment
private T field = null;
private double unusedField = 12345.67890;
private UnknownType anotherString = "Another\nStrin\g";
public static int staticField = 0;
public final int instanceFinalField = 0;
protected final int protectedField = 0;
final int packagePrivateField = 0;
//months is not a var, is a constant becuase of `final` /**
public static final int year = 2021; * Semantic highlighting:
* Generated spectrum to pick colors for local variables and parameters:
public static void showMenu(){ * Color#1 SC1.1 SC1.2 SC1.3 SC1.4 Color#2 SC2.1 SC2.2 SC2.3 SC2.4 Color#3
Scanner keyboard = new Scanner(System.in); * Color#3 SC3.1 SC3.2 SC3.3 SC3.4 Color#4 SC4.1 SC4.2 SC4.3 SC4.4 Color#5
int uResponse = 0; *
String test = ""; * @param param1
* @param param2
do { * @param param3
System.out.printf("\t----Menu----\n\n"); */
int time = 50; public SomeClass(AnInterface param1,
sleepText("1) Doctors", time); sleepText("2) Patient", time); sleepText("0) Exit", time); int param2,
System.out.printf("\nType here 👉 "); int param3) {
int reassignedValue = this.staticField + param2 + param3;
do { long localVar1, localVar2, localVar3, localVar4;
try { int localVar = "IntelliJ"; // Error, incompatible types
try { System.out.println(anotherString + toString() + localVar);
test = keyboard.nextLine(); //receive whatever input int sum = protectedField + packagePrivateField + staticField;
if (test.isEmpty()) { long time = parse("1.2.3"); // Method is deprecated
throw new NullPointerException("var is empty"); new Thread().countStackFrames(); // Method is deprecated and marked for removal
} else { reassignedValue++;
sleepFor(500); field.run();
uResponse = Integer.parseInt(test); //parse that input into an Integer (not an int) new SomeClass() {
break; {
int a = localVar;
} }
} catch(NullPointerException e) { };
System.out.printf("\nRemember you must type at least ony number from 0-2\n"); showMenu(); int[] l = new ArrayList<String>().toArray(new int[CONSTANT]);
}
} catch (NumberFormatException e) {
//TODO: handle exception
clearScreen();
System.out.printf("\n\nERROR (❌): this program only accepts integers\n\n");
showMenu();
}
} while (true);
switch (uResponse) {
case 0:
System.out.printf("Goodbye! Hope I helped!\n");
System.exit(0);
break;
case 1:
clearScreen();
if (AuthenticationMenu.startAuthMenu(1) == true) { DoctorMenu.showDoctorMenu(); } else { System.out.printf("Something went wrong :)\n"); }
break;
case 2:
clearScreen();
if (AuthenticationMenu.startAuthMenu(2) == true) { PatientMenu.showPatientMenu(); } else { System.out.printf("Something went wrong :)\n"); }
//PatientMenu.showPatientMenu();
break;
default:
System.out.print("\033[H\033[2J"); System.out.flush();
System.out.printf("ERROR (❌): command not recognized\ntry again ↓\n");
}
} while (uResponse != 0);
} }
} }
enum AnEnum {CONST1, CONST2}
interface AnInterface {
int CONSTANT = 2;
void method();
}
abstract class SomeAbstractClass {
protected int instanceField = staticField;
}

33
samples/javascript.js Normal file
View file

@ -0,0 +1,33 @@
var globalVar;
/**
* Constructor for AjaxRequest class
* @param {string} url the url for the request<p/>
*/
function AjaxRequest(url) {
function local() {}
var urls = [ "www.cnn.com", 5, globalVar];
this.request = new XMLHttpRequest();
url = url.replace(/^\s*(.*)/, "$1"); // skip leading whitespace
/* check the url to be in urls */
var a = "\u1111\z\n\u11";
this.foo = new function() {};
foo();
#
var hello = () => console.log("hello")
}
@decorator()
class NameClass {
}
declare module name{
declare export var exportedVar: string;
declare export function exportedFunction(): void;
declare export class ExportedClass {}
}
interface MyInterface { }
type FooBarAlias = string;
var html =`<div title='HTML injection'>Injected language fragment</div>`;
var x: MyInterface, y: string, z: FooBarAlias;

View file

@ -1,28 +0,0 @@
const Generator = require("yeoman-generator")
const chalk = require('chalk')
const yosay = require("yosay")
module.exports = class extends Generator {
prompting() {
// have yeoman greet the user
this.log(chalk.red("Let\'s do this"))
const prompts = [{
message: 'Enter the excercise title',
worker: true,
action: null,
age: 123
}];
return this.prompt(prompts).then(props => {
// you can access them later
this.props = props
})
}
}
function exclamate(message) {
return message + "!"
}
console.log(exclamate("lol"))

View file

@ -1,88 +0,0 @@
import { SET_TOKEN } from "./authTypes";
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
//the json is not ok
return false;
}
//the json is ok
return true;
}
export const login = async (data, dispatchToken) => {
const requestOptions = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(data),
};
try {
const response = await fetch(
`http://127.0.0.1:8000/api/token`,
requestOptions
);
if (response.ok) {
const res = await response.json();
window.localStorage.setItem("userToken", res.token);
dispatchToken({ type: SET_TOKEN, token: res.token });
return {
ok: true,
successMessage: "Login Successfull.",
errors: null,
};
} else {
const res = await response.json();
return {
ok: false,
successMessage: null,
errors: { password: res.errors["non_field_errors"] },
};
}
} catch (error) {
alert(error);
}
};
export const register = async (data, dispatchToken) => {
const requestOptions = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(data),
};
try {
const response = await fetch(
`http://127.0.0.1:8000/api/register`,
requestOptions
);
if (response.ok) {
const res = await response.json();
window.localStorage.setItem("userToken", res.token);
dispatchToken({ type: SET_TOKEN, token: res.token });
return {
ok: true,
successMessage: "Register Successfull.",
errors: null,
};
} else {
const res = await response.json();
return {
ok: false,
successMessage: null,
errors: res["errors"],
};
}
} catch (error) {
alert(error);
}
};

View file

@ -1,24 +1,19 @@
{ {
"name": "Catppuccin", // Line comments are not included in standard but nonetheless allowed.
"version": "1.0.0", /* As well as block comments. */
"description": "JSON sample", "the only keywords are": [
"main": "readme.md", true,
"scripts": { false,
"gulp": "gulp" null
],
"strings with": {
"no escapes": "pseudopolinomiality"
"valid escapes": "C-style\r\n and unicode\u0021",
"illegal escapes": "\0377\x\"
}, },
"devDependencies": { "some numbers": [
"gulp": "^4.0.2", 42,
"browser-sync": "^2.27.5", -0.0e-0,
"gulp-sass": "^5.0.0", 6.626e-34
"gulp-uglify-es": "^2.0.0", ]
"sass": "^1.35.1"
},
"repository": {
"type": "git",
"url": "https://github.com/catppuccin/catppuccin"
},
"keywords": ["gulp", "pugjs", "sass", "coffeescript", "template"],
"author": "John Doe",
"license": "MIT",
"homepage": "https://github.com/catppuccin"
} }

68
samples/kotlin.kt Normal file
View file

@ -0,0 +1,68 @@
/* Block comment */
package hello
import kotlin.collections.* // line comment
/**
* Doc comment here for `SomeClass`
* @see Iterator#next()
*/
@Deprecated(message = "Deprecated class")
private class MyClass<out T : Iterable<T>>(var prop1: Int) {
fun foo(nullable: String?, r: Runnable, f: () -> Int, fl: FunctionLike, dyn: dynamic) {
println("length\nis ${nullable?.length} \e")
println(nullable!!.length)
val ints = java.util.ArrayList<Int?>(2)
ints[0] = 102 + f() + fl()
val myFun = { -> "" };
var ref = ints.size
ints.lastIndex + globalCounter
ints.forEach lit@{
if (it == null) return@lit
println(it + ref)
}
dyn.dynamicCall()
dyn.dynamicProp = 5
val klass = MyClass::class
val year = java.time.LocalDate.now().year
}
override fun hashCode(): Int {
return super.hashCode() * 31
}
}
fun Int?.bar() {
if (this != null) {
println(message = toString())
} else {
println(this.toString())
}
}
var globalCounter: Int = 5
get() = field
abstract class Abstract {
val bar get() = 1
fun test() {
bar
}
}
object Obj
enum class E { A, B }
interface FunctionLike {
operator fun invoke() = 1
}
typealias Predicate<T> = (T) -> Boolean
fun baz(p: Predicate<Int>) = p(42)
suspend fun suspendCall() =
suspendFn()
suspend fun suspendFn() {}

View file

@ -1,41 +1,27 @@
local M = {} ---@class Emmy
local var = {} -- a short comment
local a, b, c = true, false, nil
--region my class members region
local api ---@alias MyType Emmy
local line_text = { here = "hey" }
local test_tbl = {
num = 0,
bool = true,
str = "aye!",
something = line_text.here
}
--- @class example --- doc comment
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan dapibus ex, ---@param par1 Par1Type @comments
-- duis tincidunt consectetur nisl at auctor. Mauris et dictum urna, ac maximus mi. function var:fun(par1, par2)
function M:render(line_info, startline, endline) print('hello')
startline = startline or 0 return self.len + 2
endline = endline or api.nvim_buf_line_count(self.buffer)
local lines = {}
for index, line in pairs(line_info) do
local line_no = index
local column = 1
if #line > 0 then
for _, segment in ipairs(line) do
table.insert(self.highlights, {
range = { line_no, column, #segment.text },
color_group = segment.color_group,
})
end
end
table.insert(lines, line_text)
end
api.nvim_buf_set_lines(self.buffer, startline, endline, true, lines)
self:_set_highlights()
end end
return M ---@overload fun(name:string):Emmy
function var.staticFun()
end
--endregion end my class members region
---@return Emmy
function findEmmy()
return "string" .. var
end
globalVar = {
property = value
}

174
samples/markdown.md Normal file
View file

@ -0,0 +1,174 @@
Test Markdown document
======================
Text
----
Here is a paragraph with bold text. **This is some bold text.** Here is a
paragraph with bold text. __This is also some bold text.__
Here is another one with italic text. *This is some italic text.* Here is
another one with italic text. _This is some italic text._
Here is another one with struckout text. ~~This is some struckout text.~~
Links
-----
Autolink: <http://example.com>
Link: [Example](http://example.com)
Reference style [link][1].
[1]: http://example.com "Example"
Images
------
Image: ![My image](http://www.foo.bar/image.png)
Headers
-------
# First level title
## Second level title
### Third level title
#### Fourth level title
##### Fifth level title
###### Sixth level title
### Title with [link](http://localhost)
### Title with ![image](http://localhost)
Code
----
```
This
is
code
fence
```
Inline `code span in a` paragraph.
This is a code block:
/**
* Sorts the specified array into ascending numerical order.
*
* <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
* by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
* offers O(n log(n)) performance on many data sets that cause other
* quicksorts to degrade to quadratic performance, and is typically
* faster than traditional (one-pivot) Quicksort implementations.
*
* @param a the array to be sorted
*/
public static void sort(byte[] a) {
DualPivotQuicksort.sort(a);
}
Quotes
------
> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.
> A list within a blockquote:
>
> * asterisk 1
> * asterisk 2
> * asterisk 3
> Formatting within a blockquote:
>
> ### header
> Link: [Example](http://example.com)
Html
-------
This is inline <span>html</html>.
And this is an html block.
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
<tr>
<td>Row 1 Cell 1</td>
<td>Row 1 Cell 2</td>
</tr>
<tr>
<td>Row 2 Cell 1</td>
<td>Row 2 Cell 2</td>
</tr>
</table>
Horizontal rules
----------------
---
___
***
Lists
-----
Unordered list:
* asterisk 1
* asterisk 2
* asterisk 3
Ordered list:
1. First
2. Second
3. Third
Mixed:
1. First
2. Second:
* Fee
* Fie
* Foe
3. Third
Definition list:
Some term
: First definition
: Second definition
Tables:
| Header 1 | Header 2 |
| -------- | -------- |
| Data 1 | Data 2 |

View file

@ -1,172 +1,32 @@
import sys @decorator(param=1)
import os def f(x):
import re """
Syntax Highlighting Demo
@param x Parameter
from i18n import _ Semantic highlighting:
Generated spectrum to pick colors for local variables and parameters:
Color#1 SC1.1 SC1.2 SC1.3 SC1.4 Color#2 SC2.1 SC2.2 SC2.3 SC2.4 Color#3
Color#3 SC3.1 SC3.2 SC3.3 SC3.4 Color#4 SC4.1 SC4.2 SC4.3 SC4.4 Color#5
"""
from importlib.machinery import SourceFileLoader def nested_func(y):
print(y + 1)
s = ("Test", 2+3, {'a': 'b'}, f'{x!s:{"^10"}}') # Comment
f(s[0].lower())
nested_func(42)
class RubberStamp: class Foo:
"""Howdy rubber stamp""" tags: List[str]
UI_TEXT = "ui_text" def __init__(self: Foo):
UI_SUBTEXT = "ui_subtext" byte_string: bytes = b'newline:\n also newline:\x0a'
text_string = u"Cyrillic Я is \u042f. Oops: \u042g"
self.make_sense(whatever=1)
def set_ui_text(self, text, type=None): def make_sense(self, whatever):
"""Convert an ui string to input howdy-gtk understands""" self.sense = whatever
typedec = "M"
if type == self.UI_SUBTEXT: x = len('abc')
typedec = "S" print(f.__doc__)
return self.send_ui_raw(typedec + "=" + text)
def send_ui_raw(self, command):
"""Write raw command to howdy-gtk stdin"""
if self.config.getboolean("debug", "verbose_stamps", fallback=False):
print("Sending command to howdy-gtk: " + command)
# Add a newline because the ui reads per line
command += " \n"
if self.gtk_proc:
# Send the command as bytes
self.gtk_proc.stdin.write(bytearray(command.encode("utf-8")))
self.gtk_proc.stdin.flush()
def execute(config, gtk_proc, opencv):
verbose = config.getboolean("debug", "verbose_stamps", fallback=False)
dir_path = os.path.dirname(os.path.realpath(__file__))
installed_stamps = []
# Go through each file in the rubberstamp folder
for filename in os.listdir(dir_path):
# Remove non-readable file or directories
if not os.path.isfile(dir_path + "/" + filename):
continue
# Remove meta files
if filename in ["__init__.py", ".gitignore"]:
continue
# Add the found file to the list of enabled rubberstamps
installed_stamps.append(filename.split(".")[0])
if verbose: print("Installed rubberstamps: " + ", ".join(installed_stamps))
# Get the rules defined in the config
raw_rules = config.get("rubberstamps", "stamp_rules")
rules = raw_rules.split("\n")
# Go through the rules one by one
for rule in rules:
rule = rule.strip()
if len(rule) <= 1:
continue
# Parse the rule with regex
regex_result = re.search("^(\w+)\s+([\w\.]+)\s+([a-z]+)(.*)?$", rule, re.IGNORECASE)
# Error out if the regex did not match (invalid line)
if not regex_result:
print(_("Error parsing rubberstamp rule: {}").format(rule))
continue
type = regex_result.group(1)
# Error out if the stamp name in the rule is not a file
if type not in installed_stamps:
print(_("Stamp not installed: {}").format(type))
continue
# Load the module from file
module = SourceFileLoader(type, dir_path + "/" + type + ".py").load_module()
# Try to get the class with the same name
try:
constructor = getattr(module, type)
except AttributeError:
print(_("Stamp error: Class {} not found").format(type))
continue
# Init the class and set common values
instance = constructor()
instance.verbose = verbose
instance.config = config
instance.gtk_proc = gtk_proc
instance.opencv = opencv
# Set some opensv shorthands
instance.video_capture = opencv["video_capture"]
instance.face_detector = opencv["face_detector"]
instance.pose_predictor = opencv["pose_predictor"]
instance.clahe = opencv["clahe"]
# Parse and set the 2 required options for all rubberstamps
instance.options = {
"timeout": float(re.sub("[a-zA-Z]", "", regex_result.group(2))),
"failsafe": regex_result.group(3) != "faildeadly"
}
# Try to get the class do declare its other config variables
try:
instance.declare_config()
except Exception:
print(_("Internal error in rubberstamp configuration declaration:"))
import traceback
traceback.print_exc()
continue
# Split the optional arguments at the end of the rule by spaces
raw_options = regex_result.group(4).split()
# For each of those aoptional arguments
for option in raw_options:
# Get the key to the left, and the value to the right of the equal sign
key, value = option.split("=")
# Error out if a key has been set that was not declared by the module before
if key not in instance.options:
print("Unknow config option for rubberstamp " + type + ": " + key)
continue
# Convert the argument string to an int or float if the declared option has that type
if isinstance(instance.options[key], int):
value = int(value)
elif isinstance(instance.options[key], float):
value = float(value)
instance.options[key] = value
if verbose:
print("Stamp \"" + type + "\" options parsed:")
print(instance.options)
print("Executing stamp")
# Make the stamp fail by default
result = False
# Run the stamp code
try:
result = instance.run()
except Exception:
print(_("Internal error in rubberstamp:"))
import traceback
traceback.print_exc()
continue
if verbose: print("Stamp \"" + type + "\" returned: " + str(result))
# Abort authentication if the stamp returned false
if result is False:
if verbose: print("Authentication aborted by rubber stamp")
sys.exit(14)
# This is outside the for loop, so we've run all the rules
if verbose: print("All rubberstamps processed, authentication successful")
# Exit with no errors
sys.exit(0)

View file

@ -1,815 +0,0 @@
# source: https://github.com/gornostal/Modific
# -*- coding: utf-8 -*-
from __future__ import print_function
import sublime
import sublime_plugin
import os
import threading
import subprocess
import functools
import re
from copy import copy
IS_ST3 = sublime.version().startswith('3') or sublime.version().startswith('4')
def get_settings():
return sublime.load_settings("Modific.sublime-settings")
def get_vcs_settings():
"""
Returns list of dictionaries
each dict. represents settings for VCS
"""
default = [
{"name": "git", "dir": ".git", "cmd": "git"},
{"name": "svn", "dir": ".svn", "cmd": "svn"},
{"name": "bzr", "dir": ".bzr", "cmd": "bzr"},
{"name": "hg", "dir": ".hg", "cmd": "hg"},
{"name": "tf", "dir": "$tf", "cmd": "C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/TF.exe"}
]
settings = get_settings().get('vcs', default)
# re-format settings array if user has old format of settings
if type(settings[0]) == list:
settings = [dict(name=name, cmd=cmd, dir='.'+name) for name, cmd in settings]
return settings
def get_user_command(vcs_name):
"""
Returns command that user specified for vcs_name
"""
try:
return [vcs['cmd'] for vcs in get_vcs_settings() if vcs.get('name') == vcs_name][0]
except IndexError:
return None
def tfs_root(directory):
try:
tf_cmd = get_user_command('tf') or 'tf'
command = [tf_cmd, 'workfold', directory]
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
shell=True, universal_newlines=False)
out, err = p.communicate()
m = re.search(r"^ \$\S+: (\S+)$", out, re.MULTILINE)
if m:
return {'root': m.group(1), 'name': 'tf', 'cmd': tf_cmd}
except:
return None
def get_vcs(directory):
"""
Determines root directory for VCS and which of VCS systems should be used for a given directory
Returns dictionary {name: .., root: .., cmd: .., dir: ..}
"""
vcs_check = [(lambda vcs: lambda dir: os.path.exists(os.path.join(dir, vcs.get('dir', False)))
and vcs)(vcs) for vcs in get_vcs_settings()]
start_directory = directory
while directory:
available = list(filter(bool, [check(directory) for check in vcs_check]))
if available:
available[0]['root'] = directory
return available[0]
parent = os.path.realpath(os.path.join(directory, os.path.pardir))
if parent == directory: # /.. == /
# try TFS as a last resort
# I'm not sure why we need to do this. Seems like it should find root for TFS in the main loop
return tfs_root(start_directory)
directory = parent
return None
def main_thread(callback, *args, **kwargs):
# sublime.set_timeout gets used to send things onto the main thread
# most sublime.[something] calls need to be on the main thread
sublime.set_timeout(functools.partial(callback, *args, **kwargs), 0)
def _make_text_safeish(text, fallback_encoding, method='decode'):
# The unicode decode here is because sublime converts to unicode inside
# insert in such a way that unknown characters will cause errors, which is
# distinctly non-ideal... and there's no way to tell what's coming out of
# git in output. So...
try:
unitext = getattr(text, method)('utf-8')
except (UnicodeEncodeError, UnicodeDecodeError):
unitext = getattr(text, method)(fallback_encoding)
except AttributeError:
# strongly implies we're already unicode, but just in case let's cast
# to string
unitext = str(text)
return unitext
def do_when(conditional, callback, *args, **kwargs):
if conditional():
return callback(*args, **kwargs)
sublime.set_timeout(functools.partial(do_when, conditional, callback, *args, **kwargs), 50)
def log(*args, **kwargs):
"""
@param *args: string arguments that should be logged to console
@param debug=True: debug log mode
@param settings=None: instance of sublime.Settings
"""
debug = kwargs.get('debug', True)
settings = kwargs.get('settings', None)
if not settings:
settings = get_settings()
if debug and not settings.get('debug', False):
return
print('Modific:', *args)
class CommandThread(threading.Thread):
def __init__(self, command, on_done, working_dir="", fallback_encoding="", console_encoding="", **kwargs):
threading.Thread.__init__(self)
self.command = command
self.on_done = on_done
self.working_dir = working_dir
if 'stdin' in kwargs:
self.stdin = kwargs['stdin'].encode()
else:
self.stdin = None
self.stdout = kwargs.get('stdout', subprocess.PIPE)
self.console_encoding = console_encoding
self.fallback_encoding = fallback_encoding
self.kwargs = kwargs
def run(self):
try:
# Per http://bugs.python.org/issue8557 shell=True is required to
# get $PATH on Windows. Yay portable code.
shell = os.name == 'nt'
if self.console_encoding:
self.command = [s.encode(self.console_encoding) for s in self.command]
proc = subprocess.Popen(self.command,
stdout=self.stdout, stderr=subprocess.STDOUT,
stdin=subprocess.PIPE,
cwd=self.working_dir if self.working_dir != '' else None,
shell=shell, universal_newlines=False)
output = proc.communicate(self.stdin)[0]
if not output:
output = ''
# if sublime's python gets bumped to 2.7 we can just do:
# output = subprocess.check_output(self.command)
main_thread(self.on_done,
_make_text_safeish(output, self.fallback_encoding), **self.kwargs)
except subprocess.CalledProcessError as e:
main_thread(self.on_done, e.returncode)
except OSError as e:
if e.errno == 2:
main_thread(sublime.error_message,
"'%s' binary could not be found in PATH\n\nConsider using `vcs` property to specify PATH\n\nPATH is: %s" % (self.command[0], os.environ['PATH']))
else:
raise e
class EditViewCommand(sublime_plugin.TextCommand):
def run(self, edit, command=None, output='', begin=0, region=None):
"""
For some reason Sublime's view.run_command() doesn't allow to pass tuples,
therefore region must be a list
"""
region = sublime.Region(int(region[0]), int(region[1])) if region else None
if command == 'insert':
self.view.insert(edit, int(begin), output)
elif command == 'replace':
self.view.replace(edit, region, output)
elif command == 'erase':
self.view.erase(edit, region)
else:
print('Invalid command: ', command)
raise
class VcsCommand(object):
may_change_files = False
def __init__(self, *args, **kwargs):
self.settings = get_settings()
super(VcsCommand, self).__init__(*args, **kwargs)
def log(self, *args, **kwargs):
return log(settings=self.settings, *args, **kwargs)
def run_command(self, command, callback=None, show_status=False,
filter_empty_args=True, **kwargs):
if filter_empty_args:
command = [arg for arg in command if arg]
if 'working_dir' not in kwargs:
kwargs['working_dir'] = self.get_working_dir()
if 'fallback_encoding' not in kwargs and self.active_view() and self.active_view().settings().get('fallback_encoding'):
kwargs['fallback_encoding'] = self.active_view().settings().get('fallback_encoding').rpartition('(')[2].rpartition(')')[0]
kwargs['console_encoding'] = self.settings.get('console_encoding')
autosave = self.settings.get('autosave', True)
if self.active_view() and self.active_view().is_dirty() and autosave:
self.active_view().run_command('save')
if not callback:
callback = self.generic_done
log('run command:', ' '.join(command))
thread = CommandThread(command, callback, **kwargs)
thread.start()
if show_status:
message = kwargs.get('status_message', False) or ' '.join(command)
sublime.status_message(message + 'wef')
def generic_done(self, result):
self.log('generic_done', result)
if self.may_change_files and self.active_view() and self.active_view().file_name():
if self.active_view().is_dirty():
result = "WARNING: Current view is dirty.\n\n"
else:
# just asking the current file to be re-opened doesn't do anything
print("reverting")
position = self.active_view().viewport_position()
self.active_view().run_command('revert')
do_when(lambda: not self.active_view().is_loading(),
lambda: self.active_view().set_viewport_position(position, False))
if not result.strip():
return
self.panel(result)
def _output_to_view(self, output_file, output, clear=False,
syntax="Packages/Diff/Diff.tmLanguage"):
output_file.set_syntax_file(syntax)
if clear:
output_file.run_command('edit_view', dict(command='replace', region=[0, self.output_view.size()], output=output))
else:
output_file.run_command('edit_view', dict(command='insert', output=output))
def scratch(self, output, title=False, position=None, **kwargs):
scratch_file = self.get_window().new_file()
if title:
scratch_file.set_name(title)
scratch_file.set_scratch(True)
self._output_to_view(scratch_file, output, **kwargs)
scratch_file.set_read_only(True)
if position:
sublime.set_timeout(lambda: scratch_file.set_viewport_position(position), 0)
return scratch_file
def panel(self, output, **kwargs):
if not hasattr(self, 'output_view'):
self.output_view = self.get_window().get_output_panel("vcs")
self.output_view.set_read_only(False)
self._output_to_view(self.output_view, output, clear=True, **kwargs)
self.output_view.set_read_only(True)
self.get_window().run_command("show_panel", {"panel": "output.vcs"})
def _active_file_name(self):
view = self.active_view()
if view and view.file_name() and len(view.file_name()) > 0:
return view.file_name()
def active_view(self):
return self.view
def get_window(self):
if (hasattr(self, 'view') and hasattr(self.view, 'window')):
return self.view.window()
else:
return sublime.active_window()
def get_working_dir(self):
return os.path.dirname(self._active_file_name())
def is_enabled(self):
file_name = self._active_file_name()
if file_name and os.path.exists(file_name):
return bool(get_vcs(self.get_working_dir()))
return False
class DiffCommand(VcsCommand):
""" Here you can define diff commands for your VCS
method name pattern: %(vcs_name)s_diff_command
"""
def run(self, edit):
vcs = get_vcs(self.get_working_dir())
filepath = self.view.file_name()
filename = os.path.basename(filepath)
max_file_size = self.settings.get('max_file_size', 1024) * 1024
if not os.path.exists(filepath) or os.path.getsize(filepath) > max_file_size:
# skip large files
return
get_command = getattr(self, '{0}_diff_command'.format(vcs['name']), None)
if get_command:
self.run_command(get_command(filename), self.diff_done)
def diff_done(self, result):
self.log('diff_done', result)
def git_diff_command(self, file_name):
vcs_options = self.settings.get('vcs_options', {}).get('git') or ['--no-color', '--no-ext-diff']
return [get_user_command('git') or 'git', 'diff'] + vcs_options + ['--', file_name]
def svn_diff_command(self, file_name):
params = [get_user_command('svn') or 'svn', 'diff']
params.extend(self.settings.get('vcs_options', {}).get('svn', []))
if '--internal-diff' not in params and self.settings.get('svn_use_internal_diff', True):
params.append('--internal-diff')
# if file starts with @, use `--revision HEAD` option
# https://github.com/gornostal/Modific/issues/17
if file_name.find('@') != -1:
file_name += '@'
params.extend(['--revision', 'HEAD'])
params.append(file_name)
return params
def bzr_diff_command(self, file_name):
vcs_options = self.settings.get('vcs_options', {}).get('bzr', [])
return [get_user_command('bzr') or 'bzr', 'diff'] + vcs_options + [file_name]
def hg_diff_command(self, file_name):
vcs_options = self.settings.get('vcs_options', {}).get('hg', [])
return [get_user_command('hg') or 'hg', 'diff'] + vcs_options + [file_name]
def tf_diff_command(self, file_name):
vcs_options = self.settings.get('vcs_options', {}).get('tf') or ['-format:unified']
return [get_user_command('tf') or 'tf', 'diff'] + vcs_options + [file_name]
def get_line_ending(self):
return '\n'
def join_lines(self, lines):
"""
Join lines using os.linesep.join(), unless another method is specified in ST settings
"""
return self.get_line_ending().join(lines)
class ShowDiffCommand(DiffCommand, sublime_plugin.TextCommand):
def diff_done(self, result):
self.log('on show_diff', result)
if not result.strip():
return
result = result.replace('\r\n', '\n')
file_name = re.findall(r'([^\\\/]+)$', self.view.file_name())
scratch = self.scratch(result, title="Diff - " + file_name[0])
# Select the line in the diff output where the cursor is located.
point = self.view.sel()[0].b
region = self.view.line(point)
line = self.view.substr(region)
region = scratch.find(line, 0, sublime.LITERAL)
scratch.show_at_center(region)
scratch.sel().clear()
# Place the cursor at the beginning of the line
scratch.sel().add(scratch.line(region).a)
class DiffParser(object):
instance = None
def __init__(self, diff):
self.diff = diff
self.chunks = None
self.__class__.instance = self
def _append_to_chunks(self, start, lines):
self.chunks.append({
"start": start,
"end": start + len(lines),
"lines": lines
})
def get_chunks(self):
if self.chunks is None:
self.chunks = []
diff = self.diff.strip()
if diff:
re_header = re.compile(r'^@@[0-9\-, ]+\+(\d+)', re.S)
current = None
lines = []
for line in diff.splitlines():
# ignore lines with '\' at the beginning
if line.startswith('\\'):
continue
matches = re.findall(re_header, line)
if matches:
if current is not None:
self._append_to_chunks(current, lines)
current = int(matches[0])
lines = []
elif current:
lines.append(line)
if current is not None and lines:
self._append_to_chunks(current, lines)
return self.chunks
def get_lines_to_hl(self):
inserted = []
changed = []
deleted = []
for chunk in self.get_chunks():
current = chunk['start']
deleted_line = None
for line in chunk['lines']:
if line.startswith('-'):
if (not deleted_line or deleted_line not in deleted):
deleted.append(current)
deleted_line = current
elif line.startswith('+'):
if deleted_line:
deleted.pop()
deleted_line = None
changed.append(current)
elif current - 1 in changed:
changed.append(current)
else:
inserted.append(current)
current += 1
else:
deleted_line = None
current += 1
return inserted, changed, deleted
def get_original_part(self, line_num):
""" returns a chunk of code that relates to the given line
and was there before modifications
return (lines list, start_line int, replace_lines int)
"""
# for each chunk from diff:
for chunk in self.get_chunks():
# if line_num is within that chunk
if chunk['start'] <= line_num <= chunk['end']:
ret_lines = []
current = chunk['start'] # line number that corresponds to current version of file
first = None # number of the first line to change
replace_lines = 0 # number of lines to change
return_this_lines = False # flag shows whether we can return accumulated lines
for line in chunk['lines']:
if line.startswith('-') or line.startswith('+'):
first = first or current
if current == line_num:
return_this_lines = True
if line.startswith('-'):
# if line starts with '-' we have previous version
ret_lines.append(line[1:])
else:
# if line starts with '+' we only increment numbers
replace_lines += 1
current += 1
elif return_this_lines:
break
else:
# gap between modifications
# reset our variables
current += 1
first = current
replace_lines = 0
ret_lines = []
if return_this_lines:
return ret_lines, first, replace_lines
return None, None, None
class HlChangesCommand(DiffCommand, sublime_plugin.TextCommand):
def hl_lines(self, lines, hl_key):
if (not len(lines) or not self.settings.get('highlight_changes')):
self.view.erase_regions(hl_key)
return
icon = self.settings.get('region_icon') or 'modific'
if icon == 'none':
return
if icon == 'modific':
if IS_ST3:
icon = 'Packages/Modific/icons/' + hl_key + '.png'
else:
icon = '../Modific/icons/' + hl_key
points = [self.view.text_point(l - 1, 0) for l in lines]
regions = [sublime.Region(p, p) for p in points]
self.view.add_regions(hl_key, regions, "markup.%s.diff" % hl_key, icon, sublime.HIDDEN | sublime.DRAW_EMPTY)
def diff_done(self, diff):
self.log('on hl_changes:', diff)
if diff and '@@' not in diff:
# probably this is an error message
# if print raise UnicodeEncodeError, try to encode string to utf-8 (issue #35)
try:
print(diff)
except UnicodeEncodeError:
print(diff.encode('utf-8'))
diff_parser = DiffParser(diff)
(inserted, changed, deleted) = diff_parser.get_lines_to_hl()
self.log('new lines:', inserted)
self.log('modified lines:', changed)
self.log('deleted lines:', deleted)
self.hl_lines(inserted, 'inserted')
self.hl_lines(deleted, 'deleted')
self.hl_lines(changed, 'changed')
class ShowOriginalPartCommand(DiffCommand, sublime_plugin.TextCommand):
def run(self, edit):
diff_parser = DiffParser.instance
if not diff_parser:
return
(row, col) = self.view.rowcol(self.view.sel()[0].begin())
(lines, start, replace_lines) = diff_parser.get_original_part(row + 1)
if lines is not None:
self.panel(self.join_lines(lines))
class ReplaceModifiedPartCommand(DiffCommand, sublime_plugin.TextCommand):
def run(self, edit):
self.view.run_command('save')
diff_parser = DiffParser.instance
if not diff_parser:
return
(row, col) = self.view.rowcol(self.view.sel()[0].begin())
(lines, current, replace_lines) = diff_parser.get_original_part(row + 1)
if self.settings.get('debug'):
print('replace', (lines, current, replace_lines))
if lines is not None:
begin = self.view.text_point(current - 1, 0)
content = self.join_lines(lines)
if replace_lines:
end = self.view.line(self.view.text_point(replace_lines + current - 2, 0)).end()
region = sublime.Region(begin, end)
if lines:
self.view.run_command('edit_view', dict(command='replace', region=[region.begin(), region.end()], output=content))
else:
region = self.view.full_line(region)
self.view.run_command('edit_view', dict(command='erase', region=[region.begin(), region.end()]))
else:
self.view.run_command('edit_view', dict(command='insert', begin=begin,
output=content + self.get_line_ending()))
self.view.run_command('save')
class HlChangesBackground(sublime_plugin.EventListener):
def on_load(self, view):
if not IS_ST3:
view.run_command('hl_changes')
def on_load_async(self, view):
view.run_command('hl_changes')
def on_activated(self, view):
if not IS_ST3:
view.run_command('hl_changes')
def on_activated_async(self, view):
view.run_command('hl_changes')
def on_post_save(self, view):
if not IS_ST3:
view.run_command('hl_changes')
def on_post_save_async(self, view):
view.run_command('hl_changes')
class JumpBetweenChangesCommand(DiffCommand, sublime_plugin.TextCommand):
def run(self, edit, direction='next'):
lines = self._get_lines()
if not lines:
return
if direction == 'prev':
lines.reverse()
(current_line, col) = self.view.rowcol(self.view.sel()[0].begin())
current_line += 1
jump_to = None
for line in lines:
if direction == 'next' and current_line < line:
jump_to = line
break
if direction == 'prev' and current_line > line:
jump_to = line
break
if not jump_to and self.settings.get('jump_between_changes_wraps_around', True):
jump_to = lines[0]
if jump_to is not None:
self.goto_line(edit, jump_to)
def goto_line(self, edit, line):
# Convert from 1 based to a 0 based line number
line = int(line) - 1
# Negative line numbers count from the end of the buffer
if line < 0:
lines, _ = self.view.rowcol(self.view.size())
line = lines + line + 1
pt = self.view.text_point(line, 0)
self.view.sel().clear()
self.view.sel().add(sublime.Region(pt))
self.view.show(pt)
def _get_lines(self):
diff_parser = DiffParser.instance
if not diff_parser:
return
(inserted, changed, deleted) = diff_parser.get_lines_to_hl()
lines = list(set(inserted + changed + deleted))
lines.sort()
prev = None
ret_lines = []
for line in lines:
if prev != line - 1:
ret_lines.append(line)
prev = line
return ret_lines
class UncommittedFilesCommand(VcsCommand, sublime_plugin.WindowCommand):
def active_view(self):
return self.window.active_view()
def is_enabled(self):
return bool(self.get_working_dir())
def get_working_dir(self):
if self._active_file_name():
working_dir = super(UncommittedFilesCommand, self).get_working_dir()
if working_dir and get_vcs(working_dir):
return working_dir
# If the user has opened a vcs folder, use it.
folders = self.window.folders()
for folder in folders:
if folder and os.path.exists(folder) and get_vcs(folder):
return folder
def run(self):
self.vcs = get_vcs(self.get_working_dir())
status_command = getattr(self, '{0}_status_command'.format(self.vcs['name']), None)
if status_command:
self.run_command(status_command(), self.status_done, working_dir=self.vcs['root'])
def git_status_command(self):
return [get_user_command('git') or 'git', 'status', '--porcelain']
def svn_status_command(self):
return [get_user_command('svn') or 'svn', 'status', '--quiet']
def bzr_status_command(self):
return [get_user_command('bzr') or 'bzr', 'status', '-S', '--no-pending', '-V']
def hg_status_command(self):
return [get_user_command('hg') or 'hg', 'status']
def tf_status_command(self):
return [get_user_command('tf') or 'tf', 'status']
def filter_unified_status(self, result):
return list(filter(lambda x: len(x) > 0 and not x.lstrip().startswith('>'),
result.rstrip().replace('"', '').split('\n')))
def git_filter_status(self, result):
return self.filter_unified_status(result)
def svn_filter_status(self, result):
return self.filter_unified_status(result)
def bzr_filter_status(self, result):
return self.filter_unified_status(result)
def hg_filter_status(self, result):
return self.filter_unified_status(result)
def tf_filter_status(self, result):
filtered = []
can_add = False
for line in result.split('\n'):
if line.startswith('$'):
can_add = True
continue
if line == '':
can_add = False
continue
if can_add:
filtered.append(line)
return filtered
def git_status_file(self, file_name):
# first 2 characters are status codes, the third is a space
return file_name[3:]
def svn_status_file(self, file_name):
return file_name[8:]
def bzr_status_file(self, file_name):
return file_name[4:]
def hg_status_file(self, file_name):
return file_name[2:]
def tf_status_file(self, file_name):
try:
# assume that file name should always contain colon
return re.findall(r'\s+(\S+:.+)$', file_name)[0]
except:
return None
def status_done(self, result):
filter_status = getattr(self, '{0}_filter_status'.format(self.vcs['name']), None)
self.results = [item.replace('\r', '') for item in filter_status(result)]
if self.results:
self.show_status_list()
else:
sublime.status_message("Nothing to show")
def show_status_list(self):
options = copy(self.results)
options.insert(0, " - Open All")
if self.settings.get('uncommitted_files_use_monospace_font', True):
self.get_window().show_quick_panel(options, self.panel_done, sublime.MONOSPACE_FONT)
else:
self.get_window().show_quick_panel(options, self.panel_done)
def panel_done(self, picked):
if picked == 0:
self.open_files(*self.results)
return
elif 0 > picked < len(self.results):
return
picked_file = self.results[picked - 1]
self.open_files(picked_file)
def open_files(self, *files):
for f in files:
get_file = getattr(self, '{0}_status_file'.format(self.vcs['name']), None)
if get_file:
fname = get_file(f)
if os.path.isfile(os.path.join(self.vcs['root'], fname)):
self.window.open_file(os.path.join(self.vcs['root'], fname))
else:
sublime.status_message("File '{0}' doesn't exist".format(fname))
class ToggleHighlightChangesCommand(sublime_plugin.TextCommand):
def run(self, edit):
setting_name = "highlight_changes"
settings = get_settings()
is_on = settings.get(setting_name)
if is_on:
# remove highlighting
[self.view.erase_regions(k) for k in ('inserted', 'changed', 'deleted')]
else:
self.view.run_command('hl_changes')
settings.set(setting_name, not is_on)
sublime.save_settings("Modific.sublime-settings")

View file

@ -1,35 +0,0 @@
# Simple Python Sample
from __future__ import print_function
import os
import threading
import sublime
IS_ST3 = sublime.version().startswith('3')
def get_vcs_settings():
"""Returns list of dictionaries"""
if self.config.getboolean("verbose_stamps", fallback=False):
print("Sending " + command)
# Add a newline because the ui reads per line
command += " \n"
if self.gtk_proc:
# Send the command as bytes
self.gtk_proc.stdin.write(bytearray(command.encode("utf-8")))
self.gtk_proc.stdin.flush()
try:
constructor = getattr(module, type)
except AttributeError:
print(_("Error: Class {} not found").format(type))
continue
else
instance = constructor()
instance.verbose = verbose
instance.config = config
def do_when(conditional, callback, *args, **kwargs):
if conditional():
return callback(*args, **kwargs)
sublime.set_timeout(functools.partial(do_when, conditional, callback, *args, **kwargs), 50)

117
samples/rust.rs Normal file
View file

@ -0,0 +1,117 @@
#[macro_use]
extern crate log;
use std::collections::HashMap;
use std::rc::Rc;
mod stuff;
pub enum Flag {
Good,
Bad,
Ugly
}
const QUALITY: Flag = Flag::Good;
struct Table<const N: usize>([[i32; N]; N])
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
}
struct Object<T> {
flag: Flag,
fields: HashMap<T, u64>
}
union MyUnion {
f1: u32,
f2: f32,
}
type RcObject<T> = Rc<Object<T>>;
impl<T> Write for Object<T> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let s = stuff::write_map(&self.fields, buf)?;
info!("{} byte(s) written", s);
Ok(s)
}
}
impl<T> Default for Object<T> {
fn default() -> Self {
Object { flag: Flag::Good, fields: HashMap::new() }
}
}
macro_rules! make_wrapper {
($wrapper_ty:ident, $base_ty:ty $(, $lu_ty:ty)?) => {
pub struct $wrapper_ty($base_ty);
impl From<$base_ty> for $wrapper_ty {
fn from(base: $base_ty) -> Self {
Self(base)
}
}
$(
impl From<$lu_ty> for $wrapper_ty {
fn from(lu: $lu_ty) -> Self {
Self(lu.get())
}
}
impl From<$wrapper_ty> for $lu_ty {
fn from(st: $wrapper_ty) -> Self {
Self::new(st.0)
}
}
)?
}
}
/* Block comment */
fn main() {
// A simple integer calculator:
// `+` or `-` means add or subtract by 1
// `*` or `/` means multiply or divide by 2
stuff::AppVersion::print();
let input = Option::None;
let program = input.unwrap_or_else(|| "+ + * - /");
let mut accumulator = 0;
for token in program.chars() {
match token {
'+' => accumulator += 1,
'-' => accumulator -= 1,
'*' => accumulator *= 2,
'/' => accumulator /= 2,
_ => { /* ignore everything else */ }
}
}
info!("The program \"{}\" calculates the value {}",
program, accumulator);
}
/// Some documentation `with a code`, *an italic text*
/// and **a bold text**
/// # Heading
/// [Rust](https://www.rust-lang.org/)
#[cfg(target_os="linux")]
unsafe fn a_function<T: 'lifetime>(count: &mut i64) -> ! {
count += 1;
'label: loop {
let str_with_escapes = "Hello\x20W\u{f3}rld!\u{abcdef}";
println!("{} {foo:<4}", str_with_escapes, foo = 42);
}
}
fn test() {
unsafe {
a_function(1);
}
}
#[cfg(feature = "disabled_feature")]
fn cfg_disabled_function() {}

View file

@ -1,45 +0,0 @@
#![warn(rust_2018_idioms)]
#![allow(elided_lifetimes_in_paths)]
use std::net::TcpListener;
use std::io;
use std::thread::spawn;
use std::collections::HashMap;
let solar_distance = HashMap::from([
("Mercury", 0.4),
("Venus", 0.7),
("Earth", 1.0),
("Mars", 1.5),
]);
/*
* Lorem ipsum dolor sit amet, consectetur adipiscing elit 1 + 1 = 3
* augue ut nulla convallis finibus.
* */
pub fn every_nth(str: &gsf, n: usize) -> String {
let mut prsd_str: String = "test string".to_string().to_owned();
let lenght:usize = gsf.len();
for (i, j) in gsf.chars().enumerate() {
if length%2 == 0 {
if i%n < n-1 {
parsed_str.push();
}
} else {
if i%n < n-2 {
parsed_str.push(gsf.substr(i, j));
}
}
}
return parsed_str;
}
fn main(){
let arr:[i32;4] = [10,20,30,40];
println!("array is {:?}",arr);
println!("array size is :{}",arr.len());
for index in 0..4 {
println!("index is: {} & value is : {}",index,arr[index]);
}
}

View file

@ -1,961 +0,0 @@
use crate::context::DrawContext;
use crate::controller::Controller;
use crate::font::FontCache;
use crate::scene::*;
use crate::wayland::*;
use crate::*;
use smithay_client_toolkit::reexports::calloop::{EventLoop, LoopHandle, RegistrationToken};
use smithay_client_toolkit::seat::keyboard::ModifiersState;
use smithay_client_toolkit::shm::AutoMemPool;
use smithay_client_toolkit::WaylandSource;
use std::cell::RefCell;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use smithay_client_toolkit::reexports::client::{
global_filter,
protocol::wl_buffer::WlBuffer,
protocol::wl_callback,
protocol::wl_compositor::WlCompositor,
protocol::wl_output::{self, WlOutput},
protocol::wl_pointer::{self, WlPointer},
protocol::wl_region::WlRegion,
protocol::wl_seat::{self, Capability, WlSeat},
protocol::wl_shm::WlShm,
protocol::wl_surface::WlSurface,
Attached, Display, GlobalError, GlobalManager, Interface, Main, Proxy,
};
use smithay_client_toolkit::reexports::protocols::wlr::unstable::layer_shell::v1::client::{
zwlr_layer_shell_v1::ZwlrLayerShellV1, zwlr_layer_surface_v1,
zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
};
pub struct Application<M, C>
where
C: Controller<M> + Clone + 'static,
{
display: Display,
globals: Rc<RefCell<Globals>>,
global_manager: GlobalManager,
pub inner: Vec<InnerApplication<M, C>>,
token: RegistrationToken,
}
struct Context {
pending_cb: bool,
time: Option<u32>,
render_node: Option<RenderNode>,
font_cache: FontCache,
}
pub struct CoreApplication<M, C>
where
C: Controller<M> + Clone,
{
pub controller: C,
ctx: Context,
globals: Rc<RefCell<Globals>>,
mempool: AutoMemPool,
widget: Box<dyn Widget<M>>,
surface: Option<Surface>,
}
pub struct InnerApplication<M, C>
where
C: Controller<M> + Clone,
{
core: CoreApplication<M, C>,
cb: Box<dyn FnMut(&mut CoreApplication<M, C>, Event<M>)>,
}
impl Surface {
fn new(
surface: Main<WlSurface>,
shell: Shell,
region: Main<WlRegion>,
previous: Option<Surface>,
) -> Self {
Surface {
alive: true,
surface,
shell,
region,
previous: if let Some(surface) = previous {
Some(Box::new(surface))
} else {
None
},
buffer: None,
}
}
fn commit(&mut self) {
self.surface.commit();
std::mem::drop(&mut self.previous);
self.previous = None;
}
fn destroy(&mut self) {
self.alive = false;
self.surface.destroy();
self.region.destroy();
self.shell.destroy();
if let Some(buffer) = self.buffer.as_ref() {
buffer.destroy();
}
self.buffer = None;
}
fn destroy_previous(&mut self) {
if let Some(surface) = self.previous.as_mut() {
surface.destroy();
}
self.previous = None;
}
fn set_size(&self, width: u32, height: u32) {
self.shell.set_size(width, height);
}
fn damage(&self, report: &[Region]) {
self.surface.attach(self.buffer.as_ref(), 0, 0);
for d in report {
self.surface
.damage(d.x as i32, d.y as i32, d.width as i32, d.height as i32);
}
}
fn attach_buffer(&mut self, buffer: WlBuffer) {
self.buffer = Some(buffer);
}
}
impl Globals {
fn new() -> Self {
Self {
outputs: Vec::new(),
seats: Vec::new(),
shm: None,
compositor: None,
shell: None,
}
}
pub fn create_shell_surface_from<M, C>(
&self,
geometry: &dyn Widget<M>,
config: ShellConfig,
previous: Option<Surface>,
) -> Option<Surface>
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
if self.compositor.is_some() {
match config {
ShellConfig::LayerShell(config) => {
if let Some(layer_shell) = self.shell.as_ref() {
let region = self.compositor.as_ref().unwrap().create_region();
let wl_surface = self.compositor.as_ref().unwrap().create_surface();
let layer_surface = layer_shell.get_layer_surface(
&wl_surface,
config.output.as_ref(),
config.layer,
config.namespace.clone(),
);
if let Some(anchor) = &config.anchor {
layer_surface.set_anchor(*anchor);
}
wl_surface.quick_assign(|_, _, _| {});
layer_surface.set_exclusive_zone(config.exclusive);
layer_surface.set_keyboard_interactivity(config.interactivity);
layer_surface.set_size(geometry.width() as u32, geometry.height() as u32);
layer_surface.set_margin(
config.margin[0],
config.margin[1],
config.margin[2],
config.margin[3],
);
wl_surface.commit();
assign_surface::<M, C>(&layer_surface);
return Some(Surface::new(
wl_surface,
Shell::LayerShell {
surface: layer_surface,
config,
},
region,
previous,
));
}
}
}
}
None
}
pub fn create_mempool(&self) -> AutoMemPool {
let attached = Attached::from(self.shm.clone().unwrap());
AutoMemPool::new(attached).unwrap()
}
pub fn get_outputs(&self) -> Vec<Output> {
self.outputs.clone()
}
pub fn get_seats(&self) -> &[Seat] {
&self.seats
}
}
impl Output {
fn new(output: Main<WlOutput>) -> Self {
Output {
width: 0,
height: 0,
scale: 1,
name: String::new(),
output,
}
}
}
impl<M, C> Application<M, C>
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
pub fn new(pointer: bool) -> (Self, EventLoop<'static, Self>) {
let display = Display::connect_to_env().unwrap();
let event_queue = display.create_event_queue();
let attached_display = (*display).clone().attach(event_queue.token());
let display_handle = display.clone();
let globals = Globals::new();
let global_manager = GlobalManager::new_with_cb(
&attached_display,
global_filter!(
[
ZwlrLayerShellV1,
1,
|layer_shell: Main<ZwlrLayerShellV1>, mut application: DispatchData| {
if let Some(application) = application.get::<Application<M, C>>() {
if let Ok(mut globals) = application.globals.try_borrow_mut() {
globals.shell = Some(layer_shell);
}
}
}
],
[
WlShm,
1,
|shm: Main<WlShm>, mut application: DispatchData| {
shm.quick_assign(|_, _, _| {});
if let Some(application) = application.get::<Application<M, C>>() {
if let Ok(mut globals) = application.globals.try_borrow_mut() {
globals.shm = Some(shm);
}
}
}
],
[
WlCompositor,
4,
|compositor: Main<WlCompositor>, mut application: DispatchData| {
if let Some(application) = application.get::<Application<M, C>>() {
if let Ok(mut globals) = application.globals.try_borrow_mut() {
globals.compositor = Some(compositor);
}
}
}
],
[WlSeat, 7, move |seat: Main<WlSeat>, _: DispatchData| {
seat.quick_assign(move |wl_seat, event, mut application| match event {
wl_seat::Event::Capabilities { capabilities } => {
if let Some(application) = application.get::<Application<M, C>>() {
if pointer
&& capabilities & Capability::Pointer == Capability::Pointer
{
let pointer = wl_seat.get_pointer();
assign_pointer::<M, C>(&pointer);
}
if let Ok(mut globals) = application.globals.try_borrow_mut() {
let mut found = None;
for seat in &mut globals.seats {
if wl_seat.eq(&seat.seat) {
found = Some(());
seat.capabilities = capabilities;
}
}
if found.is_none() {
globals.seats.push(Seat {
capabilities,
seat: wl_seat,
});
}
}
}
}
_ => {}
});
}],
[
WlOutput,
3,
|output: Main<WlOutput>, _application: DispatchData| {
output.quick_assign(move |wl_output, event, mut application| match event {
wl_output::Event::Geometry {
x: _,
y: _,
physical_width: _,
physical_height: _,
subpixel: _,
make,
model: _,
transform: _,
} => {
if let Some(application) = application.get::<Application<M, C>>() {
if let Ok(mut globals) = application.globals.try_borrow_mut() {
let mut found = None;
for output in &mut globals.outputs {
if wl_output.eq(&output.output) {
found = Some(());
output.name = make.clone();
}
}
if found.is_none() {
let mut output = Output::new(wl_output);
output.name = make;
globals.outputs.push(output);
}
}
}
}
wl_output::Event::Mode {
flags: _,
width,
height,
refresh: _,
} => {
if let Some(application) = application.get::<Application<M, C>>() {
if let Ok(mut globals) = application.globals.try_borrow_mut() {
let mut found = None;
for output in &mut globals.outputs {
if wl_output.eq(&output.output) {
found = Some(());
output.width = width;
output.height = height;
}
}
if found.is_none() {
let mut output = Output::new(wl_output);
output.width = width;
output.height = height;
globals.outputs.push(output);
}
}
}
}
wl_output::Event::Scale { factor } => {
if let Some(application) = application.get::<Application<M, C>>() {
if let Ok(mut globals) = application.globals.try_borrow_mut() {
let mut found = None;
for output in &mut globals.outputs {
if wl_output.eq(&output.output) {
found = Some(());
output.scale = factor;
}
}
if found.is_none() {
let mut output = Output::new(wl_output);
output.scale = factor;
globals.outputs.push(output);
}
}
}
}
wl_output::Event::Done => {}
_ => {}
});
}
]
),
);
let event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!");
let token = WaylandSource::new(event_queue)
.quick_insert(event_loop.handle())
.unwrap();
let (mut application, mut event_loop) = (
Application {
display,
globals: Rc::new(RefCell::new(globals)),
global_manager,
inner: Vec::new(),
token,
},
event_loop,
);
for _ in 0..2 {
display_handle.flush().unwrap();
event_loop.dispatch(None, &mut application).unwrap();
}
(application, event_loop)
}
fn get_index(&self, surface: &WlSurface) -> usize {
for i in 0..self.inner.len() {
if self.inner[i].eq(surface) {
return i;
}
}
0
}
fn get_application(&mut self, surface: &WlSurface) -> Option<&mut InnerApplication<M, C>> {
for inner in &mut self.inner {
if inner.eq(surface) {
return Some(inner);
}
}
None
}
pub fn get_global<I>(&self) -> Result<Main<I>, GlobalError>
where
I: Interface + AsRef<Proxy<I>> + From<Proxy<I>>,
{
self.global_manager.instantiate_range::<I>(0, 1 << 8)
}
pub fn create_empty_inner_application<Data: 'static>(
&mut self,
controller: C,
widget: impl Widget<M> + 'static,
handle: LoopHandle<'_, Data>,
cb: impl FnMut(&mut CoreApplication<M, C>, Event<M>) + 'static,
) {
let inner_application =
InnerApplication::empty(controller, widget, self.globals.clone(), cb);
self.inner.push(inner_application);
handle.update(&self.token).unwrap();
}
pub fn create_inner_application_from<Data: 'static>(
&mut self,
controller: C,
config: ShellConfig,
widget: impl Widget<M> + 'static,
handle: LoopHandle<'_, Data>,
cb: impl FnMut(&mut CoreApplication<M, C>, Event<M>) + 'static,
) {
let inner_application =
InnerApplication::new(controller, widget, config, self.globals.clone(), cb);
self.inner.push(inner_application);
handle.update(&self.token).unwrap();
}
pub fn create_inner_application<Data: 'static>(
&mut self,
controller: C,
widget: impl Widget<M> + 'static,
handle: LoopHandle<'_, Data>,
cb: impl FnMut(&mut CoreApplication<M, C>, Event<M>) + 'static,
) {
let inner_application =
InnerApplication::normal(controller, widget, self.globals.clone(), cb);
self.inner.push(inner_application);
handle.update(&self.token).unwrap();
}
pub fn run(mut self, event_loop: &mut EventLoop<'static, Self>) {
loop {
self.display.flush().unwrap();
event_loop.dispatch(None, &mut self).unwrap();
}
}
}
impl<M, C> Deref for InnerApplication<M, C>
where
C: Controller<M> + Clone + 'static,
{
type Target = CoreApplication<M, C>;
fn deref(&self) -> &Self::Target {
&self.core
}
}
impl<M, C> DerefMut for InnerApplication<M, C>
where
C: Controller<M> + Clone + 'static,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.core
}
}
impl<M, C> CoreApplication<M, C>
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
pub fn poll(&mut self, ev: Event<M>) -> C {
let mut ctl = self.controller.clone();
let mut sync_ctx = SyncContext::new(&mut ctl, &mut self.ctx.font_cache);
self.widget.sync(&mut sync_ctx, ev);
ctl
}
pub fn sync(&mut self, ev: Event<M>) -> bool {
let mut sync_ctx = SyncContext::new(&mut self.controller, &mut self.ctx.font_cache);
let mut damage = self.widget.sync(&mut sync_ctx, ev);
while let Ok(msg) = sync_ctx.sync() {
damage = damage.max(self.widget.sync(&mut sync_ctx, Event::Message(&msg)));
}
if damage == Damage::Frame {
if self.ctx.time.is_none() {
self.ctx.time = Some(0);
}
}
damage.is_some() && !self.ctx.pending_cb
}
pub fn destroy(&mut self) {
if let Some(surface) = self.surface.as_mut() {
surface.destroy();
}
}
pub fn get_layer_surface(&self) -> ZwlrLayerSurfaceV1 {
match &self.surface.as_ref().unwrap().shell {
Shell::LayerShell { config: _, surface } => surface.detach(),
}
}
pub fn is_hidden(&self) -> bool {
if let Some(surface) = self.surface.as_ref() {
return !surface.alive;
} else {
true
}
}
pub fn replace_surface(&mut self) {
if let Some(surface) = self.surface.as_mut() {
surface.destroy();
surface.alive = true;
match &surface.shell {
Shell::LayerShell { config, surface: _ } => {
self.surface = self.globals.borrow().create_shell_surface_from::<M, C>(
self.widget.deref(),
ShellConfig::LayerShell(config.clone()),
Some(surface.clone()),
);
}
}
} else {
self.surface = self.globals.borrow().create_shell_surface_from::<M, C>(
self.widget.deref(),
ShellConfig::LayerShell(LayerShellConfig::default()),
None,
);
}
}
pub fn replace_surface_by(&mut self, config: ShellConfig) {
if let Some(surface) = self.surface.as_mut() {
surface.destroy();
surface.alive = true;
self.surface = self.globals.borrow().create_shell_surface_from::<M, C>(
self.widget.deref(),
config,
Some(surface.clone()),
);
} else {
self.surface = self.globals.borrow().create_shell_surface_from::<M, C>(
self.widget.deref(),
config,
None,
);
}
}
}
impl<M, C> Geometry for InnerApplication<M, C>
where
C: Controller<M> + Clone + 'static,
{
fn width(&self) -> f32 {
self.widget.width()
}
fn height(&self) -> f32 {
self.widget.height()
}
fn set_size(&mut self, width: f32, height: f32) -> Result<(), (f32, f32)> {
if let Some(surface) = self.surface.as_ref() {
surface.set_size(width as u32, height as u32);
surface.surface.commit();
}
Ok(())
}
}
impl<M, C> InnerApplication<M, C>
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
pub fn empty(
controller: C,
widget: impl Widget<M> + 'static,
globals: Rc<RefCell<Globals>>,
cb: impl FnMut(&mut CoreApplication<M, C>, Event<M>) + 'static,
) -> Self {
let mempool = globals.borrow().create_mempool();
let mut default = InnerApplication {
core: CoreApplication {
controller,
ctx: Context {
pending_cb: false,
time: None,
font_cache: FontCache::new(),
render_node: None,
},
surface: None,
widget: Box::new(widget),
mempool,
globals,
},
cb: Box::new(cb),
};
default.sync(Event::Prepare);
default
}
pub fn normal(
controller: C,
widget: impl Widget<M> + 'static,
globals: Rc<RefCell<Globals>>,
cb: impl FnMut(&mut CoreApplication<M, C>, Event<M>) + 'static,
) -> Self {
let mempool = globals.borrow().create_mempool();
let mut default = InnerApplication {
core: CoreApplication {
controller,
ctx: Context {
pending_cb: false,
time: None,
font_cache: FontCache::new(),
render_node: None,
},
surface: None,
widget: Box::new(widget),
mempool,
globals,
},
cb: Box::new(cb),
};
default.sync(Event::Prepare);
default.replace_surface();
default
}
pub fn new(
controller: C,
widget: impl Widget<M> + 'static,
config: ShellConfig,
globals: Rc<RefCell<Globals>>,
cb: impl FnMut(&mut CoreApplication<M, C>, Event<M>) + 'static,
) -> Self {
let mempool = globals.borrow().create_mempool();
let mut new = InnerApplication {
core: CoreApplication {
controller,
ctx: Context {
pending_cb: false,
time: None,
font_cache: FontCache::new(),
render_node: None,
},
surface: None,
widget: Box::new(widget),
mempool,
globals,
},
cb: Box::new(cb),
};
new.sync(Event::Prepare);
new.replace_surface_by(config);
new
}
fn eq(&self, wl_surface: &WlSurface) -> bool {
if let Some(surface) = &self.surface {
return surface.surface.detach().eq(wl_surface);
}
false
}
pub fn roundtrip(&mut self, ev: Event<M>) -> Result<RenderNode, ()> {
let width = self.width();
let height = self.height();
// Sending the event to the widget tree
if self.sync(ev) || ev.is_frame() {
// Calling the application´s closure
(self.cb)(&mut self.core, ev);
if !self.is_hidden() {
let current_width = self.width();
let current_height = self.height();
// Resizing the surface in case the widget changed size
if ev.is_frame() {
self.ctx.render_node = None;
} else if width != current_width || height != current_height {
let _ = self.set_size(current_width, current_height);
return Err(());
}
// Creating the render node
let render_node = self.core.widget.create_node(0., 0.);
self.ctx.pending_cb = true;
return Ok(render_node);
}
} else {
// Calling the application´s closure
(self.cb)(&mut self.core, ev);
}
Err(())
}
fn render(&mut self, time: u32, recent_node: RenderNode) {
let width = recent_node.width();
let height = recent_node.height();
if Some(time).ne(&self.core.ctx.time) || time == 0 {
if let Ok((buffer, wl_buffer)) =
Buffer::new(&mut self.core.mempool, width as i32, height as i32)
{
let mut v = Vec::new();
let mut ctx =
DrawContext::new(buffer.backend, &mut self.core.ctx.font_cache, &mut v);
if let Some(render_node) = self.core.ctx.render_node.as_mut() {
if let Err(region) = render_node.draw_merge(
recent_node,
&mut ctx,
&Instruction::empty(0., 0., width, height),
None,
) {
ctx.damage_region(&Background::Transparent, region, false);
}
} else {
ctx.damage_region(
&Background::Transparent,
Region::new(0., 0., width, height),
false,
);
recent_node.render(&mut ctx, None);
self.core.ctx.render_node = Some(recent_node);
}
self.core.ctx.pending_cb = false;
if let Some(surface) = self.core.surface.as_mut() {
surface.attach_buffer(wl_buffer);
surface.damage(&v);
surface.commit();
if let Some(_) = self.core.ctx.time {
self.core.ctx.time = Some(time);
frame_callback::<M, C>(time, surface.surface.clone());
}
}
}
}
}
pub fn callback(&mut self, ev: Event<M>) {
if self.ctx.time.is_none() || ev.is_cb() {
if let Ok(render_node) = self.roundtrip(ev) {
if let Some(surface) = self.surface.as_ref() {
draw_callback::<M, C>(&surface.surface, render_node);
}
}
} else {
let width = self.width();
let height = self.height();
self.sync(ev);
let current_width = self.width();
let current_height = self.height();
// Resizing the surface in case the widget changed size
if width != current_width || height != current_height {
let _ = self.set_size(current_width, current_height);
}
}
}
}
fn frame_callback<M, C>(time: u32, surface: Main<WlSurface>)
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
let h = surface.detach();
surface
.frame()
.quick_assign(move |_, event, mut application| match event {
wl_callback::Event::Done { callback_data } => {
let timeout = (callback_data - time).min(50);
if let Some(application) = application.get::<Application<M, C>>() {
if let Some(inner_application) = application.get_application(&h) {
inner_application.ctx.time = None;
inner_application.callback(Event::Callback(timeout));
}
}
}
_ => {}
});
surface.commit();
}
fn draw_callback<M, C>(surface: &Main<WlSurface>, mut recent_node: RenderNode)
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
let h = surface.detach();
surface
.frame()
.quick_assign(move |_, event, mut application| match event {
wl_callback::Event::Done { callback_data } => {
if let Some(application) = application.get::<Application<M, C>>() {
let inner_application = application.get_application(&h).unwrap();
inner_application.render(callback_data, std::mem::take(&mut recent_node));
}
}
_ => {}
});
surface.commit();
}
impl From<ModifiersState> for Modifiers {
fn from(modifer_state: ModifiersState) -> Modifiers {
Modifiers {
ctrl: modifer_state.ctrl,
alt: modifer_state.alt,
shift: modifer_state.shift,
caps_lock: modifer_state.caps_lock,
logo: modifer_state.logo,
num_lock: modifer_state.num_lock,
}
}
}
fn assign_pointer<M, C>(pointer: &Main<WlPointer>)
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
let mut index = 0;
let mut input = Pointer::Enter;
let (mut x, mut y) = (0., 0.);
pointer.quick_assign(move |_, event, mut inner| match event {
wl_pointer::Event::Leave { serial: _, surface } => {
input = Pointer::Leave;
if let Some(application) = inner.get::<Application<M, C>>() {
if let Some(inner_application) = application.get_application(&surface) {
inner_application.callback(Event::Pointer(x as f32, y as f32, input));
}
}
}
wl_pointer::Event::Button {
serial: _,
time,
button,
state,
} => {
input = Pointer::MouseClick {
time,
button: MouseButton::new(button),
pressed: state == wl_pointer::ButtonState::Pressed,
};
}
wl_pointer::Event::Frame => {
if let Some(application) = inner.get::<Application<M, C>>() {
let inner_application = application.inner.get_mut(index).unwrap();
inner_application.callback(Event::Pointer(x as f32, y as f32, input));
}
}
wl_pointer::Event::Axis {
time: _,
axis,
value,
} => {
input = Pointer::Scroll {
orientation: match axis {
wl_pointer::Axis::VerticalScroll => Orientation::Vertical,
wl_pointer::Axis::HorizontalScroll => Orientation::Horizontal,
_ => Orientation::Vertical,
},
value: value as f32,
}
}
wl_pointer::Event::Enter {
serial: _,
surface,
surface_x,
surface_y,
} => {
if let Some(application) = inner.get::<Application<M, C>>() {
x = surface_x;
y = surface_y;
index = application.get_index(&surface);
}
}
wl_pointer::Event::Motion {
time: _,
surface_x,
surface_y,
} => {
x = surface_x;
y = surface_y;
input = Pointer::Hover;
}
_ => {}
});
}
fn assign_surface<M, C>(shell: &Main<ZwlrLayerSurfaceV1>)
where
M: 'static,
C: Controller<M> + Clone + 'static,
{
shell.quick_assign(move |shell, event, mut inner| match event {
zwlr_layer_surface_v1::Event::Configure {
serial,
width,
height,
} => {
shell.ack_configure(serial);
println!("\nCONFIGURE - {} : {} X {}\n", serial, width, height);
if let Some(application) = inner.get::<Application<M, C>>() {
for inner_application in &mut application.inner {
if let Some(app_surface) = inner_application.surface.as_mut() {
match &app_surface.shell {
Shell::LayerShell { config: _, surface } => {
if shell.eq(surface) {
app_surface.destroy_previous();
let _ = inner_application
.widget
.set_size(width as f32, height as f32);
if inner_application.ctx.pending_cb {
if let Ok(render_node) =
inner_application.roundtrip(Event::Frame)
{
draw_callback::<M, C>(
&inner_application
.surface
.as_ref()
.unwrap()
.surface,
render_node,
);
}
} else {
if let Ok(render_node) =
inner_application.roundtrip(Event::Frame)
{
inner_application.render(0, render_node);
}
}
}
}
}
}
}
}
}
_ => unreachable!(),
});
}

53
samples/scala.scala Normal file
View file

@ -0,0 +1,53 @@
import scala.collection.mutable._
import java.util.TreeMap
/**
* ScalaDoc comment: <code>Some code</code>
* Html escape sequence &#94;
* ''Text''
*
* @param x Int param
* @author IntelliJ
*/
class ScalaClass(x: Int) extends ScalaObject {
1 to 5
(x: Int) => x
val field = "Some\nStrin\g"
def foo(x: Float, y: Float) = {
def empty = 2
val local = 1000 - empty
Math.sqrt(x + y + local); //this can crash
}
def t[T]: T = null
foo(0, -1) match {
case x => x
}
type G = Int
val xml = <element attibute="value">data</element>
}
/*
And now ScalaObject
*/
object Object {
val layer = -5.0
val mutableCollection = HashMap[Int, Int]()
val immutableCollection = List(1, 2)
val javaCollection = new TreeMap[Int, Int]()
def foo: ScalaClass = new ScalaClass(23, 9)
}
@Annotation(2) {val name = value}
trait Trait {
}
abstract class SomeAbstract {
for (x <- list) {
x
}
}

14
samples/sql.sql Normal file
View file

@ -0,0 +1,14 @@
-- DDL section
create table crm.product (
id numeric primary key,
title varchar(255) character set utf8
);
-- DML section
insert into product
values (1, 'Product1');
select count(*) from crm.product;
select id as ProductID, title as ProductName
from crm.product where id = :id;
\set content `cat data.txt`

32
samples/toml.toml Normal file
View file

@ -0,0 +1,32 @@
# This is a TOML document.
title = "TOML Example"
description = """
Multiline
description
"""
date = 2019-11-04T07:32:00-08:00
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
"connection_max" = 5000
enabled = true
[servers]
alpha = { ip = '10.0.0.1', dc = "eqdc10" }
beta = { ip = '10.0.0.2', dc = "eqdc10" }
[clients]
data = [ ["gamma", "delta"], [1.0, 2.0] ]
hosts = [
"alpha",
"omega",
]
valid-escapes = """\tline \"1\"
line\u00202
line 3\U0000002E
"""
invalid-escapes = "\a \u20 \U0020"

View file

@ -1,110 +1,54 @@
// src: https://github.com/n8n-io/n8n/blob/master/packages/core/src/Credentials.ts module ModuleValidator {
import checkChars = CharUtils.notWhiteSpace
import { export interface HasValidator<T> {
CredentialInformation, validateValue(): Boolean;
ICredentialDataDecryptedObject,
ICredentials,
ICredentialsEncrypted,
} from 'n8n-workflow';
import { AES, enc } from 'crypto-js';
export class Credentials extends ICredentials {
/**
* Returns if the given nodeType has access to data
*/
hasNodeAccess(nodeType: string): boolean {
// eslint-disable-next-line no-restricted-syntax
for (const accessData of this.nodesAccess) {
if (accessData.nodeType === nodeType) {
return true;
}
} }
return false; type FooBarAlias = string;
}
@decorator()
class HasValidator implements HasValidator<String> {
/* Processed values */
static validatedValue: Array<String> = ['', 'aa']
private myValue: String
/** /**
* Sets new credential object * Constructor for class
* @param valueParameter Value for <i>validation</i>
*/ */
setData(data: ICredentialDataDecryptedObject, encryptionKey: string): void { constructor(valueParameter: String) {
this.data = AES.encrypt(JSON.stringify(data), encryptionKey).toString(); this.myValue = valueParameter
HasValidator.validatedValue.push(value)
} }
/** public validateValue(): Boolean {
* Sets new credentials for given key var resultValue: Boolean = checkChars(this.myValue)
*/ return resultValue
setDataKey(key: string, data: CredentialInformation, encryptionKey: string): void {
let fullData;
try {
fullData = this.getData(encryptionKey);
} catch (e) {
fullData = {};
} }
fullData[key] = data; static createInstance(valueParameter: string): HasValidator {
return new HasValidator(valueParameter)
return this.setData(fullData, encryptionKey);
}
/**
* Returns the decrypted credential object
*/
getData(encryptionKey: string, nodeType?: string): ICredentialDataDecryptedObject {
if (nodeType && !this.hasNodeAccess(nodeType)) {
throw new Error(
`The node of type "${nodeType}" does not have access to credentials "${this.name}" of type "${this.type}".`,
);
}
if (this.data === undefined) {
throw new Error('No data is set so nothing can be returned.');
}
const decryptedData = AES.decrypt(this.data, encryptionKey);
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return JSON.parse(decryptedData.toString(enc.Utf8));
} catch (e) {
throw new Error(
'Credentials could not be decrypted. The likely reason is that a different "encryptionKey" was used to encrypt the data.',
);
} }
} }
/** function globalFunction<TypeParameter>(value: TypeParameter) { //global function
* Returns the decrypted credentials for given key return 42
*/
getDataKey(key: string, encryptionKey: string, nodeType?: string): CredentialInformation {
const fullData = this.getData(encryptionKey, nodeType);
if (fullData === null) {
throw new Error(`No data was set.`);
} }
// eslint-disable-next-line no-prototype-builtins declare var declareUrl
if (!fullData.hasOwnProperty(key)) { var varUrl = declareUrl.replace(/^\s*(.*)/, '$1').concat('\u1111\z\n\u22')
throw new Error(`No data for key "${key}" exists.`); var html = `<div title='HTML injection'>Injected language fragment</div>`
var hello = () => console.log('hello')
HasValidator.createInstance(varUrl).validateValue()
function acceptsUnion(s: string | number) {
if (typeof s === 'string') {
s
}
} }
return fullData[key]; enum EnumName {
} EnumMember
/**
* Returns the encrypted credentials to be saved
*/
getDataToSave(): ICredentialsEncrypted {
if (this.data === undefined) {
throw new Error(`No credentials were set to save.`);
}
return {
id: this.id,
name: this.name,
type: this.type,
data: this.data,
nodesAccess: this.nodesAccess,
};
} }
} }

19
samples/yaml.yaml Normal file
View file

@ -0,0 +1,19 @@
---
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
static_sidebar:
id: "foo"
name: 'side_bar'
staged_position: 1
blog_id: 1
config: |+
--- !map:HashWithIndifferentAccess
title: Static Sidebar
body: The body of a static sidebar
type: StaticSidebar
description: >
Sidebar configuration example
extensions:
- &params
auto_run: true
reload: true
- *params