28 Commits
1.8 ... master

Author SHA1 Message Date
kingToolbox
a8336c1d1e Update README.md 2025-02-10 20:26:46 +00:00
kingToolbox
b8d2cb7d18 Update README.md
Introduced support for `Tmux Integration`.
2025-01-12 02:19:14 +00:00
kingToolbox
3dc9041343 Added acknowledgement 2022-08-22 17:02:39 +08:00
kingToolbox
52b53014f9 Fix typo. 2022-07-25 06:52:23 +08:00
kingToolbox
ba078c0c7c Update features of v2.5 and roadmap of v2.6 2022-07-25 06:47:46 +08:00
kingToolbox
10304684e3 Merge pull request #917 from dnlchen/master
should be tag 2.4.0
2022-07-25 03:00:19 +08:00
Daniel Chen
13101e098b should be tag 2.4.0
please either create a tag 2.4 or fix the link.
tag 2.4.1 is also needed.
2022-07-21 10:27:43 -07:00
kingToolbox
24c96a6aa6 Add the download url of v2.5.0 Prerelease 1 2022-05-19 08:18:01 +08:00
kingToolbox
ee11e00722 Update features of v2.4 and roadmap of v2.5 2022-04-18 11:09:57 +08:00
kingToolbox
aa779b4b09 Add the download url of v2.4.0 Prerelease 1 2022-03-21 05:57:45 +08:00
kingToolbox
6c57450c56 Update features of v2.3 and roadmap of v2.4 2022-02-15 08:36:03 +08:00
kingToolbox
05ffe7e8d4 Update features of v2.2 and roadmap of v2.3 2021-11-19 04:14:39 +08:00
KingToolbox
f1a49022a9 Add a 1024x1024 WindTerm icon. 2021-07-24 02:28:12 +08:00
kingToolbox
d76580bea2 Update features of v2.1 and roadmap of v2.2 2021-07-17 23:45:41 +08:00
KingToolbox
be6e770876 A smart memory pointer. 2021-03-11 23:23:21 +08:00
KingToolbox
44cc3bb57c The timeout was not handled properly when processing the packet. 2021-03-11 23:20:16 +08:00
kingToolbox
99c095a22c Add forgotten "garbage collector". 2021-03-11 23:17:29 +08:00
kingToolbox
3bc1a009d5 Fix typo. 2021-03-11 23:11:50 +08:00
kingToolbox
07b34806ac Update features of v2.0 and roadmap of v2.1 2021-03-11 23:10:31 +08:00
kingToolbox
7a61ac2155 Fix typo. 2020-12-23 22:27:46 +08:00
kingToolbox
8cc7dcb147 Make benchmark data easier to read. 2020-12-23 21:19:56 +08:00
KingToolbox
b02dc28a9e Add Unix pty, which supports Linux/MacOs bash and so on. 2020-12-22 16:48:48 +08:00
kingToolbox
7920e91b74 Update benchmark of v1.9 and roadmap of v2.0 2020-12-22 02:47:31 +08:00
kingToolbox
771034b105 Add linux binary download link 2020-12-09 03:53:09 +08:00
kingToolbox
03fc9eb395 Add discussion link 2020-12-09 03:41:07 +08:00
kingToolbox
ad9878574c Add intro videos of windows opacity and search online 2020-11-13 20:05:40 +08:00
kingToolbox
b07c7c694e Update features and roadmap of version 1.9 2020-11-13 19:15:28 +08:00
KingToolbox
29652130fc Update screenshot of true colors and emojis 2020-11-13 19:04:26 +08:00
8 changed files with 698 additions and 76 deletions

213
README.md
View File

@@ -1,9 +1,9 @@
# WindTerm # WindTerm
A professional SSH/Telnet/Serial/Shell/Sftp client for DevOps. A Quicker and better SSH/Telnet/Serial/Shell/Sftp client for DevOps.
_Hello WindTerm :rose:, hello world!_ _Hello WindTerm :rose:, hello world!_
**We're just beginning! If you want a high performance text editor, you can try [WindEdit](https://www.github.com/kingToolbox/DIGEdit/).** **We're just beginning! If you want a high performance text editor, you can try [WindEdit](https://www.github.com/kingToolbox/WindEdit/).**
# License # License
**Completely FREE for commercial and non-commercial use without limitations.** **Completely FREE for commercial and non-commercial use without limitations.**
@@ -15,9 +15,7 @@ See [Intro Videos](https://kingtoolbox.github.io)
# Download # Download
Windows Binary: https://github.com/kingToolbox/WindTerm/releases **Linux binary**, **MacOS binary** and **Windows binary**: https://github.com/kingToolbox/WindTerm/releases
(The binary of Macos and Linux will be committed later)
# Source Code # Source Code
@@ -27,7 +25,11 @@ Open source code includes, but is not limited to, the classes that can be used i
# Issues and feature requests # Issues and feature requests
Any issues and feature requests are welcome. Please click [issues](https://github.com/kingToolbox/WindTerm/issues) to commit an issue. Any issues and feature requests are welcome.
Please click [issues](https://github.com/kingToolbox/WindTerm/issues) to commit an issue or a feature request.
Please click [Discussion](https://github.com/kingToolbox/WindTerm/discussions) to discuss anything about SSH, SFtp, Shell(Linux shell, Windows cmd and powershell), Telnet, Serial and WindTerm.
# Screenshots # Screenshots
@@ -45,19 +47,37 @@ DigeWhite Theme:
# Features # Features
### SSH, Telnet, Tcp, Serial ### SSH, Telnet, Tcp, Shell, Serial, Tmux
- SSH v2, Telnet, Raw Tcp, Serial, Shell protocols implemented. [Intro Video](https://kingtoolbox.github.io/2020/01/22/new-session/) - SSH v2, Telnet, Raw Tcp, Serial, Shell protocols implemented. [Intro Video](https://kingtoolbox.github.io/2020/01/22/new-session/)
- Supports SSH auto execution when session authenticated. - Supports SSH auto execution when session authenticated.
- Supports SSH agent forwarding. [Intro Video](https://kingtoolbox.github.io/2020/08/22/ssh_agent_forwarding/) - Supports SSH ControlMaster.
- Supports SSH ProxyCommand or ProxyJump. [Intro Video](https://kingtoolbox.github.io/2021/03/11/proxycommand/)
- Supports SSH agent. [Intro Video](https://kingtoolbox.github.io/2020/08/22/ssh_agent/)
- Supports SSH agent forwarding.
- Supports SSH auto login with password, public-key, keyboard-interactive, gssapi-with-mic. [Intro Video](https://kingtoolbox.github.io/2020/01/23/auto-login/) - Supports SSH auto login with password, public-key, keyboard-interactive, gssapi-with-mic. [Intro Video](https://kingtoolbox.github.io/2020/01/23/auto-login/)
- Supports X11 forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/x11_forwarding/) - Supports X11 forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/x11_forwarding/)
- Supports direct/local port forwarding, reverse/remote port forwarding and dynamic port forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/port_forwarding/) - Supports direct/local port forwarding, reverse/remote port forwarding and dynamic port forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/port_forwarding/)
- Supports XModem, YModem and ZModem. [Intro Video](https://kingtoolbox.github.io/tags/modem/)
- Integrated sftp, scp client, supports download, upload, remove, rename, make new file/directory and so on. [Intro Video](https://kingtoolbox.github.io/tags/transfer/) - Integrated sftp, scp client, supports download, upload, remove, rename, make new file/directory and so on. [Intro Video](https://kingtoolbox.github.io/tags/transfer/)
- Integrated local file manager, supports move to, copy to, copy from, remove, rename, make new file/directory and so on. - Integrated local file manager, supports move to, copy to, copy from, remove, rename, make new file/directory and so on.
- Supports Windows Cmd, PowerShell and Cmd, PowerShell as administrator.
- Supports Linux bash, zsh, powershell core and so on.
- Supports MacOS bash, zsh, powershell core and so on.
- **Supports `tmux integration`**. [Intro Video](https://kingtoolbox.github.io/2025/01/05/tmux-integration/)
### GUI ### GUI
- Session dialog and session tree. - **Supports Windows, MacOS and Linux.**
- **Supports Multilingual User Interface.**
- Supports Unicode 13.
- Session dialog and session tree. [Intro Video](https://kingtoolbox.github.io/2020/01/22/manage-sessions/)
- **Auto Completion.** [Intro Video](https://kingtoolbox.github.io/tags/auto-completion/)
- **Free Type Mode.** [Intro Video](https://kingtoolbox.github.io/2022/04/12/free_type_mode/)
- **Focus Mode.** [Intro Video](https://kingtoolbox.github.io/2021/06/28/ui_focus_mode/)
- **Sync Input.** [Intro Video](https://kingtoolbox.github.io/2021/05/27/sync-input/)
- **Enhanced protection of the session username and password.** [Intro Video](https://kingtoolbox.github.io/2021/03/11/protection-username-password/)
- **Command palette.** [Intro Video](https://kingtoolbox.github.io/tags/command-palette/) - **Command palette.** [Intro Video](https://kingtoolbox.github.io/tags/command-palette/)
- **Command sender.** [Intro Video](https://kingtoolbox.github.io/tags/sender/) - **Command sender.** [Intro Video](https://kingtoolbox.github.io/tags/sender/)
- **Explorer Pane.** [Intro Video](https://kingtoolbox.github.io/2021/05/27/explorer/)
- **Shell Pane.**
- **Quick Bar.** [Intro Video](https://kingtoolbox.github.io/2020/08/22/quickbar/) - **Quick Bar.** [Intro Video](https://kingtoolbox.github.io/2020/08/22/quickbar/)
- **Paste Dialog.** [Intro Video](https://kingtoolbox.github.io/2020/08/22/paste_dialog/) - **Paste Dialog.** [Intro Video](https://kingtoolbox.github.io/2020/08/22/paste_dialog/)
- **Local and remote modes with vim keybindings. (Using Shift+Enter key to switch between remote and local mode**) [Intro Video](https://kingtoolbox.github.io/2020/06/21/keyboard-modes/) - **Local and remote modes with vim keybindings. (Using Shift+Enter key to switch between remote and local mode**) [Intro Video](https://kingtoolbox.github.io/2020/06/21/keyboard-modes/)
@@ -68,19 +88,28 @@ DigeWhite Theme:
- Supports highlighting the opening and closing delimiter, such as (), [], {} and the customed delimiters. [Intro Video](https://kingtoolbox.github.io/2020/06/28/pair/) - Supports highlighting the opening and closing delimiter, such as (), [], {} and the customed delimiters. [Intro Video](https://kingtoolbox.github.io/2020/06/28/pair/)
- Supports changing the UI theme. [Intro Video](https://kingtoolbox.github.io/2020/09/18/theme/) - Supports changing the UI theme. [Intro Video](https://kingtoolbox.github.io/2020/09/18/theme/)
- Supports setting the tab color. [Intro Video](https://kingtoolbox.github.io/2020/09/18/tabbar-change-tabcolor/) - Supports setting the tab color. [Intro Video](https://kingtoolbox.github.io/2020/09/18/tabbar-change-tabcolor/)
- Supports searching over the opened tabs. [Intro Video](https://kingtoolbox.github.io/2021/03/11/tabbar-search-tab/)
- Supports closing tabs to the right. - Supports closing tabs to the right.
- Supports setting the windows transparency. [Intro video](https://kingtoolbox.github.io/2020/11/13/windows-opacity/)
- Supports select-to-copy, right-click-to-paste or middle-click-to-paste.
- Supports searching text online with Google, Bing, Github, Stackoverflow, Wikipedia and DuckDuckGo. [Intro video](https://kingtoolbox.github.io/2020/11/13/search-online/)
- Supports hiding mouse cursor while typing.
- **Supports locking screen.** [Intro video](https://kingtoolbox.github.io/2021/04/23/lock-screen/)
### Term ### Term
- Supports vt100, vt220, vt340, vt420, vt520, xterm, xterm-256-colors. - Supports vt100, vt220, vt340, vt420, vt520, xterm, xterm-256-colors.
- Supports unicode, true-color, mouse protocol, etc. - Supports unicode, emojis, true-color, mouse protocol, etc.
- Supports auto wrap mode. [Intro Video](https://kingtoolbox.github.io/2020/01/22/auto-wrap/) - Supports auto wrap mode. [Intro Video](https://kingtoolbox.github.io/2020/01/22/auto-wrap/)
- Protocols and terms can be customed. - Protocols and terms can be customed.
- All vttest tests have passed except Tektronix 4014. - All vttest tests have passed except Tektronix 4014.
### Session ### Session
- **Supports HTTP and SOCKS5 proxy.** [Intro Video](https://kingtoolbox.github.io/2020/10/17/proxy/) - **Supports HTTP and SOCKS5 proxy.** [Intro Video](https://kingtoolbox.github.io/2021/03/11/proxy-http-socks5/)
- **Supports Jump Server proxy.** [Intro Video](https://kingtoolbox.github.io/2021/03/11/proxy-jump-server/)
- Supports manual and automated session logging. [Intro Video](https://kingtoolbox.github.io/tags/logging/) - Supports manual and automated session logging. [Intro Video](https://kingtoolbox.github.io/tags/logging/)
- Rename and duplicate session. [Intro Video](https://kingtoolbox.github.io/tags/tabbar/) - Rename and duplicate session. [Intro Video](https://kingtoolbox.github.io/tags/tabbar/)
- Restore last sessions and layouts when restart. [Intro Video](https://kingtoolbox.github.io/2020/01/22/restore-sessions/) - Restore last sessions and layouts when restart. [Intro Video](https://kingtoolbox.github.io/2020/01/22/restore-sessions/)
- Supports opening a specific session or set of sessions on startup.
### Performance ### Performance
- Dynamic memory compression, typically `20%` to `90%` of the working memory load can be reduced.
- High performance, low memory, low latency. [Intro Video](https://kingtoolbox.github.io/2020/01/23/windterm-putty-performance/) - High performance, low memory, low latency. [Intro Video](https://kingtoolbox.github.io/2020/01/23/windterm-putty-performance/)
# Sftp Performance # Sftp Performance
@@ -102,7 +131,7 @@ The version of clients:
**All test data is for reference only.** **All test data is for reference only.**
- 5GB huge file (5,154,830 KB), generated by random data ### 5GB huge file (5,154,830 KB), generated by random data
| | Download Time | Download Rate | Upload Time | Upload Rate | | | Download Time | Download Rate | Upload Time | Upload Rate |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
@@ -112,7 +141,7 @@ The version of clients:
| FileZilla | 32s | 161.1 MB/s | 30s | 171.8 MB/s | | FileZilla | 32s | 161.1 MB/s | 30s | 171.8 MB/s |
| WinSCP | 81s | 63.7 MB/s | 91s | 56.7 MB/s | | WinSCP | 81s | 63.7 MB/s | 91s | 56.7 MB/s |
- 4400 files, 16 folders (107,042 KB), unzipped from [vim-7.4.1049.zip](https://github.com/vim/vim/archive/v7.4.1049.zip) ### 4400 files, 16 folders (107,042 KB), unzipped from [vim-7.4.1049.zip](https://github.com/vim/vim/archive/v7.4.1049.zip)
| | Download Time | Download Rate | Upload Time | Upload Rate | | | Download Time | Download Rate | Upload Time | Upload Rate |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
@@ -153,7 +182,9 @@ The version of terminals:
**All test data is for reference only.** **All test data is for reference only.**
- 97.6MB random text (102,401,504 bytes, 1,329,878 lines, generated and tested by [random_test.sh](https://github.com/kingToolbox/WindTerm/blob/master/benchmark/urandom_test.sh)) ## Test Command: "cat ./benchmark_randomdata"
The benchmark_randomdata contains 97.6MB random text (102,401,504 bytes, 1,329,878 lines, generated and tested by [random_test.sh](https://github.com/kingToolbox/WindTerm/blob/master/benchmark/urandom_test.sh))
In all cases, three runs were made to warm system caches. The reported numbers are the median of five runs. In all cases, three runs were made to warm system caches. The reported numbers are the median of five runs.
@@ -185,9 +216,9 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| kitty | unlimited | 17.2 | 2655 | | kitty | unlimited | 17.2 | 2655 |
| Alacritty | 100,000 | 41.3 | - | | Alacritty | 100,000 | 41.3 | - |
- time seq 1 n ## Test command: "time seq 1 n" (n = [1000000, 2000000, 5000000, 10000000], scrollback lines: unlimited)
1. n = 1,000,000, scrollback = 1,000,000 Lines ### n = 1,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
@@ -200,7 +231,7 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| Alacritty | **1.162** | Not measured, use 100,000 scrollback lines setting | | Alacritty | **1.162** | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 23.246 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 23.246 | Not measured, use 65,535 scrollback lines setting |
2. n = 2,000,000, scrollback = 2,000,000 Lines ### n = 2,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
@@ -213,33 +244,33 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| Alacritty | 2.322 | Not measured, use 100,000 scrollback lines setting | | Alacritty | 2.322 | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 50.381 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 50.381 | Not measured, use 65,535 scrollback lines setting |
3. n = 5,000,000 scrollback = 5,000,000 Lines ### n = 5,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
| WindTerm | **5.520** | **68.2** | | WindTerm | **5.520** | **68.2** |
| rxvt | 27.533 | 3166.2 | | rxvt | 27.533 | 3166.2 |
| putty | 45.911 | 2757.1 | | putty | 45.911 | 2757.1 |
| xterm | - | Out of memmory | | xterm | - | Out of memory |
| iterm2 | 10.805 | 1048.3 | | iterm2 | 10.805 | 1048.3 |
| Kitty | - | Out of memory | | Kitty | - | Out of memory |
| Alacritty | 5.799 | Not measured, use 100,000 scrollback lines setting | | Alacritty | 5.799 | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 130.371 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 130.371 | Not measured, use 65,535 scrollback lines setting |
4. n = 10,000,000 scrollback = 10,000,000 Lines ### n = 10,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
| WindTerm | **10.674** | **133.3** | | WindTerm | **10.674** | **133.3** |
| rxvt | - | Out of memory | | rxvt | - | Out of memory |
| putty | - | Out of memory | | putty | - | Out of memory |
| xterm | - | Out of memmory | | xterm | - | Out of memory |
| iterm2 | 20.468 | 2231.3 | | iterm2 | 20.468 | 2231.3 |
| Kitty | - | Out of memory | | Kitty | - | Out of memory |
| Alacritty | 11.598 | Not measured, use 100,000 scrollback lines setting | | Alacritty | 11.598 | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 264.739 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 264.739 | Not measured, use 65,535 scrollback lines setting |
5. n = 10,000,000 scrollback = 30 Lines ### n = 10,000,000 scrollback = 30 Lines
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
@@ -252,6 +283,55 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| Alacritty | 11.798 | Not measured, use zero scrollback lines setting | | Alacritty | 11.798 | Not measured, use zero scrollback lines setting |
| Windows Terminal + ssh.exe | 261.096 | Not measured, use zero scrollback lines setting | | Windows Terminal + ssh.exe | 261.096 | Not measured, use zero scrollback lines setting |
# Linux Terminal Performance
The hardware used for generating the data in these benchmarks was
Debian 10 Vm - 4cpu and 4GB memory.
For WindTerm: No color scheme used in windterm. Color scheme will result in approximately 2% loss and more memory usage.
For other terminals: No memory usage measured because most of them write the history to disk or only support a limited number of lines in memory..
The version of terminals:
| Application | Version | Release Date |
| --- | --- | --- |
| Windterm | v1.9 | 2020-12-22 |
| Gnome | v3.30.2 | 2018-10-22 |
| Mate Terminal | v1.20.2 | 2019-02-11 |
| Konsole | v18.04.0 | 2019-04-12 |
| Xfce4 Terminal | v0.8.7.4 | 2018-5-15 |
| QTerminal | v0.14.1 | 2019-01-26 |
**All test data is for reference only.**
## Test Command: "cat ./benchmark_randomdata"
The benchmark_randomdata contains 97.6MB random text (102,401,504 bytes, 1,329,878 lines, generated and tested by [random_test.sh](https://github.com/kingToolbox/WindTerm/blob/master/benchmark/urandom_test.sh))
In all cases, three runs were made to warm system caches. The reported numbers are the median of five runs.
| | Cost Time |
| --- | --- |
| WindTerm | **1.976s** |
| Gnome Terminal | 9.781s |
| Mate Terminal | 9.841s |
| Konsole | 25.050s |
| xfce4 Terminal | 10.520s |
| QTerminal | 20.763s |
## Test command: "time seq 1 n" (n = [1000000, 2000000, 5000000, 10000000], scrollback lines: unlimited)
| n | 1,000,000 | 2,000,000 | 5,000,000 | 10,000,000 | 10,000,000<br>(scrollback lines: 100) |
| --- | --- | --- | --- | --- | --- |
| WindTerm | 0.846s (18.6MB) | **1.574s** (26.6MB) | **4.046s** (56.4MB) | **8.232s** (102.2MB) | **7.748s** (3.4MB) |
| Gnome Terminal | 0.920s | 2.152s | 5.271s | 11.111s | 13.109s |
| Mate Terminal | **0.822s** | 1.698s | 5.943s | 10.920s | 12.290s |
| Konsole | 1.612s | 3.199s | 8.157s | 16.029s | 15.650s |
| xfce4 Terminal | 0.870s | 2.160s | 5.866s | 12.089s | 13.304s |
| QTerminal | 9.272s | 18.391s | 45.999s | 104.277s | 17.208s |
# Latency # Latency
Considering the network influence on the latency, the following data is from [WindEdit](https://github.com/kingToolbox/digedit). Considering the network influence on the latency, the following data is from [WindEdit](https://github.com/kingToolbox/digedit).
@@ -265,69 +345,33 @@ DIGEdit is the text component of WindTerm.
# Shortcuts # Shortcuts
| Shortcut | Action | [Shortcut Keys List](https://kingtoolbox.github.io/tags/keyboard/)
| --- | --- |
| Alt+C | Copy |
| Alt+D | Show command palette |
| Alt+F | Find |
| Alt+F3 | Find next |
| Alt+Shift+F3 | Find previous |
| Alt+F4 | Exit |
| Alt+M, Alt+F | Toggle full screen |
| Alt+M, Alt+H | Toggle hex view |
| Alt+N | New session |
| Alt+O | Open session |
| Alt+S | Save text |
| Alt+T, Alt+B | Toggle margin blank |
| Alt+T, Alt+F | Toggle margin fold |
| Alt+T, Alt+N | Toggle margin number |
| Alt+T, Alt+S | Toggle margin symbol |
| Alt+V | Paste |
| Alt+W, Alt+D | Close active dock |
| Alt+W, Alt+G | Close active group |
| Alt+W, Alt+H | Split horizontally |
| Alt+W, Alt+L | Show outline pane |
| Alt+W, Alt+V | Split vertically |
| Alt+X | Copy and paste |
| Alt+- | Zoom in |
| Alt++ | Zoom out |
| Alt+\[ | Activate next view |
| Alt+] | Activate previous view |
| Ctrl+. | Jump to next fold |
| Ctrl+, | Jump to previous fold |
| Ctrl+Shift+A | Select all text |
| Ctrl+Shift+T | Reopen closed session |
| Ctrl+Shift+W | Close current session |
| Ctrl+Shift+- | Select current fold text |
| Shift+Del | Copy |
| Shift+End | Jump to document end |
| Shift+Home | Jump to document home |
| Shift+Ins | Paste |
| Shift+PgDown | Jump to next page |
| Shift+PgUp | Jump to previous page |
# Roadmap # Roadmap
**Release cycle:** **Release cycle:**
2-4 weeks. 2-3 months.
**Next release (Early Novemberfor reference only):** **Prerelease cycle:**
- **Linux Version**
- Linux bash 4~6 weeks
- Windows Opacity
- Xmodem, Ymodem, Zmodem(sz, rz) # Roadmap of v2.7 (February 2025, for reference only)
- **Resolve issues as much as possible**
- SSH Agent Forwaring
- Tmux integration
- Command Snippet [Description](https://github.com/kingToolbox/WindTerm/issues/239#issuecomment-951934488) (Postponed to a later version )
- SSH GSSAPI Authentication (Postponed to a later version )
- Search in sessions (Postponed to a later version )
Download: [WindTerm 2.7.0 Prerelease 3](https://github.com/kingToolbox/WindTerm/releases/tag/2.7-prerelease-3) (2025-2-10)
**Roadmap of version 2.x:**
- External tools - External tools
**Todo list:**
- Protocols: - Protocols:
- Mosh
- Rlogin - Rlogin
- SSH
- ProxyCommand
- UI:
- Config dialog
- Terminal:
- MacOs bash
- Session: - Session:
- Auto Complete - Auto Complete
- Chat mode - Chat mode
@@ -336,3 +380,20 @@ DIGEdit is the text component of WindTerm.
- ftp, ftps - ftp, ftps
- Script, macro and plugin stystem - Script, macro and plugin stystem
- More ... - More ...
**Release Schedule:**
Version | Level | Target | Status | Timeline
------------ | ------------- | -------------- | ---------- | -----------
v0.x | Basic | Basic framework and basic features, but complete a high-performance text editor ([WindEdit](https://github.com/kingToolbox/WindEdit)) as the base, and be able to use them normally. | Finished | Long long ago ~ Sprint of 2020
v1.x | Manual | Perfect features and can be used by most developers in their daily work | Finished | Spring of 2020 ~ Winter of 2020
**v2.x** | **Semi automatic** | **Through triggers, macros, events, notifications and so on, developers can be assisted to complete some operations.** | **Developing** | **Spring of 2021 ~ Summer of 2022**
v3.x | Fully automatic | Through plugins, scripts, machine learning and so on, automatically operating with achieving non-attended | Planning | Summer of 2022 ~ Winter of 2023
# Acknowledgement
| | Contribution |
| ---------- | ------------- |
| [EvoWebFrance](https://github.com/EvoWebFrance) | French translation |
| [kvnklk](https://github.com/kvnklk) | German translation |
| [Lemonawa](https://github.com/Lemonawa) | Simplified Chinese translation |
| [LuxNegra](https://github.com/LuxNegra) | French translation |
| [MosamXu](https://github.com/MosamXu) | Simplified Chinese translation |

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 KiB

After

Width:  |  Height:  |  Size: 425 KiB

328
src/Pty/UnixPty.cpp Normal file
View File

@@ -0,0 +1,328 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "UnixPty.h"
#ifdef Q_OS_UNIX
#include <QFileInfo>
#include <QThread>
#include <errno.h>
#include <utmpx.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
constexpr int BUFFER_SIZE = 0x800; // 2048 bytes
ShellProcess::ShellProcess()
: QProcess()
, m_handleMaster(-1)
, m_handleSlave(-1)
{
setProcessChannelMode(QProcess::MergedChannels);
}
void ShellProcess::setupChildProcess() {
dup2(m_handleSlave, STDIN_FILENO);
dup2(m_handleSlave, STDOUT_FILENO);
dup2(m_handleSlave, STDERR_FILENO);
pid_t sid = setsid();
ioctl(m_handleSlave, TIOCSCTTY, 0);
tcsetpgrp(m_handleSlave, sid);
struct utmpx utmpxInfo;
memset(&utmpxInfo, 0, sizeof(utmpxInfo));
strncpy(utmpxInfo.ut_user, qgetenv("USER"), sizeof(utmpxInfo.ut_user));
QString device(m_handleSlaveName);
if (device.startsWith("/dev/")) {
device = device.mid(5);
}
const char *d = device.toLatin1().constData();
strncpy(utmpxInfo.ut_line, d, sizeof(utmpxInfo.ut_line));
strncpy(utmpxInfo.ut_id, d + strlen(d) - sizeof(utmpxInfo.ut_id), sizeof(utmpxInfo.ut_id));
struct timeval tv;
gettimeofday(&tv, 0);
utmpxInfo.ut_tv.tv_sec = tv.tv_sec;
utmpxInfo.ut_tv.tv_usec = tv.tv_usec;
utmpxInfo.ut_type = USER_PROCESS;
utmpxInfo.ut_pid = getpid();
utmpxname(_PATH_UTMPX);
setutxent();
pututxline(&utmpxInfo);
endutxent();
#if !defined(Q_OS_UNIX)
updwtmpx(_PATH_UTMPX, &loginInfo);
#endif
}
UnixPty::UnixPty(QObject *parent /*= nullptr*/)
: Pty(parent)
, m_pid(0)
, m_readMasterNotify(nullptr)
{
m_buffer = static_cast<char *>(malloc(BUFFER_SIZE));
}
UnixPty::~UnixPty() {
stop();
free(m_buffer);
m_buffer = nullptr;
}
bool UnixPty::createProcess(QString command, const QString &arguments,
const QString &workingDirectory, const QProcessEnvironment &environment,
int rows, int columns) {
if (m_shellProcess.state() == QProcess::Running) {
return false;
}
QFileInfo fileInfo(command);
if (fileInfo.isRelative() || fileInfo.exists() == false) {
setErrorString(tr("UnixPty: shell file path must be absolute"));
return false;
}
bool success = false;
do {
int result = 0;
m_shellProcess.m_handleMaster = ::posix_openpt(O_RDWR | O_NOCTTY);
if (m_shellProcess.m_handleMaster < 0) {
setError("Unable to open master");
break;
}
m_shellProcess.m_handleSlaveName = ptsname(m_shellProcess.m_handleMaster);
if (m_shellProcess.m_handleSlaveName.isEmpty()) {
setError("Unable to get slave name");
break;
}
result = grantpt(m_shellProcess.m_handleMaster);
if (result != 0) {
setError("Unable to change perms for slave");
break;
}
result = unlockpt(m_shellProcess.m_handleMaster);
if (result != 0) {
setError("Unable to unlock slave");
break;
}
m_shellProcess.m_handleSlave = ::open(m_shellProcess.m_handleSlaveName.toLatin1().data(), O_RDWR | O_NOCTTY);
if (m_shellProcess.m_handleSlave < 0) {
setError("Unable to open slave");
break;
}
int flags = fcntl(m_shellProcess.m_handleMaster, F_GETFL, 0);
result = fcntl(m_shellProcess.m_handleMaster, F_SETFL, flags | O_NONBLOCK);
if (result == -1) {
setError("Unable to set non-blocking mode for master");
break;
}
result = fcntl(m_shellProcess.m_handleMaster, F_SETFD, FD_CLOEXEC);
if (result == -1) {
setError("Unable to set flags for master");
break;
}
result = fcntl(m_shellProcess.m_handleSlave, F_SETFD, FD_CLOEXEC);
if (result == -1) {
setError("Unable to set flags for slave");
break;
}
struct ::termios ttmode;
if (terminalAttributes(&ttmode) == false) {
break;
}
ttmode.c_iflag |= IXON;
ttmode.c_iflag |= IUTF8;
ttmode.c_lflag |= ECHO;
#ifdef Q_OS_MACOS
ttmode.c_cc[VDSUSP] = 25;
ttmode.c_cc[VSTATUS] = 20;
#endif
if (setTerminalAttributes(&ttmode) == false) {
break;
}
m_readMasterNotify = new QSocketNotifier(m_shellProcess.m_handleMaster, QSocketNotifier::Read, &m_shellProcess);
m_readMasterNotify->setEnabled(true);
m_readMasterNotify->moveToThread(m_shellProcess.thread());
QObject::connect(m_readMasterNotify, &QSocketNotifier::activated, [this](int socket) {
Q_UNUSED(socket)
int readSize = 0;
QByteArray readData;
do {
readSize = ::read(m_shellProcess.m_handleMaster, m_buffer, BUFFER_SIZE);
if (readSize == -1) {
if (errno == EAGAIN) {
QThread::yieldCurrentThread();
continue;
} else {
break;
}
}
readData.append(QByteArray::fromRawData(m_buffer, readSize));
} while (readSize == BUFFER_SIZE || (readSize == -1 && errno == EAGAIN)); //last data block always < readSize
if (readData.isEmpty() == false) {
m_shellReadBuffer.append(readData);
emit readyRead();
}
});
m_shellProcess.setWorkingDirectory(workingDirectory);
m_shellProcess.setProcessEnvironment(environment);
m_shellProcess.setReadChannel(QProcess::StandardOutput);
m_shellProcess.start(command, arguments.isEmpty() ? QStringList() : QStringList(arguments));
m_shellProcess.waitForStarted();
m_pid = m_shellProcess.processId();
success = resizeWindow(rows, columns);
} while(0);
if (success == false) {
stop();
}
Q_ASSERT(success == true);
return success;
}
bool UnixPty::resizeWindow(int rows, int columns) {
if (rows != m_rows || columns != m_columns) {
bool success = false;
struct winsize winSize;
memset(&winSize, 0, sizeof(winSize));
winSize.ws_row = static_cast<quint16>(rows);
winSize.ws_col = static_cast<quint16>(columns);
if (ioctl(m_shellProcess.m_handleMaster, TIOCSWINSZ, &winSize) == 0
&& ioctl(m_shellProcess.m_handleSlave, TIOCSWINSZ, &winSize) == 0) {
m_rows = rows;
m_columns = columns;
success = true;
}
return success;
}
return true;
}
void UnixPty::setError(const char *error) {
Pty::setErrorString(QString("%1: %2 -> %3").arg(tr("UnixPty"), tr(error), strerror(errno)));
}
bool UnixPty::setTerminalAttributes(struct ::termios *ttmode) {
Q_ASSERT(m_shellProcess.m_handleMaster >= 0);
int result = -1;
if (m_shellProcess.m_handleMaster >=0) {
result = tcsetattr(m_shellProcess.m_handleMaster, TCSANOW, ttmode);
if (result != 0) {
setError("Unable to set terminal attributes");
}
}
return (result == 0);
}
void UnixPty::stop() {
m_shellProcess.m_handleSlaveName = QString();
if (m_shellProcess.m_handleSlave >= 0) {
::close(m_shellProcess.m_handleSlave);
m_shellProcess.m_handleSlave = -1;
}
if (m_shellProcess.m_handleMaster >= 0) {
::close(m_shellProcess.m_handleMaster);
m_shellProcess.m_handleMaster = -1;
}
if (m_shellProcess.state() == QProcess::Running) {
m_readMasterNotify->disconnect();
m_readMasterNotify->deleteLater();
m_shellProcess.terminate();
m_shellProcess.waitForFinished(1000);
if (m_shellProcess.state() == QProcess::Running) {
QProcess::startDetached(QString("kill -9 %1").arg(m_pid));
m_shellProcess.kill();
m_shellProcess.waitForFinished(1000);
}
Q_ASSERT(m_shellProcess.state() == QProcess::NotRunning);
}
}
bool UnixPty::terminalAttributes(struct ::termios *ttmode) {
Q_ASSERT(m_shellProcess.m_handleMaster >= 0);
int result = -1;
if (m_shellProcess.m_handleMaster >= 0) {
result = tcgetattr(m_shellProcess.m_handleMaster, ttmode);
if (result != 0) {
setError("Unable to get terminal attributes");
}
}
return (result == 0);
}
QByteArray UnixPty::readAll() {
QByteArray shellReadBuffer = m_shellReadBuffer;
m_shellReadBuffer.clear();
return shellReadBuffer;
}
qint64 UnixPty::write(const QByteArray &text) {
int writeSize = ::write(m_shellProcess.m_handleMaster, text.constData(), text.size());
Q_ASSERT(writeSize == text.size());
if (writeSize == -1) {
setError("Unable to write output");
}
return writeSize;
}
bool UnixPty::isAvailable() {
return true;
}
void UnixPty::moveToThread(QThread *targetThread) {
m_shellProcess.moveToThread(targetThread);
}
#endif // Q_OS_UNIX

83
src/Pty/UnixPty.h Normal file
View File

@@ -0,0 +1,83 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UNIXPTY_H
#define UNIXPTY_H
#pragma once
#include <QtGlobal>
#ifdef Q_OS_UNIX
#include "Pty.h"
#include <QProcess>
#include <QSocketNotifier>
#include <termios.h>
class ShellProcess
: public QProcess
{
Q_OBJECT
public:
ShellProcess();
private:
void setupChildProcess() final;
private:
int m_handleMaster;
int m_handleSlave;
QString m_handleSlaveName;
private:
friend class UnixPty;
};
class UnixPty
: public Pty
{
public:
UnixPty(QObject *parent = nullptr);
virtual ~UnixPty();
bool createProcess(QString command, const QString &arguments,
const QString &workingDirectory, const QProcessEnvironment &environment,
int rows, int columns) final;
static bool isAvailable();
bool resizeWindow(int rows, int columns) final;
QByteArray readAll() final;
qint64 write(const QByteArray &text) final;
private:
void moveToThread(QThread *targetThread);
void setError(const char *error);
bool setTerminalAttributes(struct ::termios *ttmode);
void stop();
bool terminalAttributes(struct ::termios *ttmode);
private:
qint64 m_pid;
ShellProcess m_shellProcess;
QSocketNotifier *m_readMasterNotify;
char *m_buffer;
QByteArray m_shellReadBuffer;
};
#endif // Q_OS_UNIX
#endif // UNIXPTY_H

View File

@@ -30,6 +30,10 @@ A quick circular buffer template class.
A very safe encryption class using the PBKDF2-algorithm as defined in RFC 8018. WindTerm uses this class together with the user's master password to protect user data, including passwords, private keys and so on. A very safe encryption class using the PBKDF2-algorithm as defined in RFC 8018. WindTerm uses this class together with the user's master password to protect user data, including passwords, private keys and so on.
## Utility/MemoryPointer.h
A smart memory pointer.
## Utility/ScopeGuard.h ## Utility/ScopeGuard.h
A class of which the sole purpose is to run the function f in its destructor. This is useful for guaranteeing your cleanup code is executed. A class of which the sole purpose is to run the function f in its destructor. This is useful for guaranteeing your cleanup code is executed.

140
src/Utility/MemoryPointer.h Normal file
View File

@@ -0,0 +1,140 @@
#ifndef MEMORYPOINTER_H
#define MEMORYPOINTER_H
#pragma once
#include <QtGlobal>
template <typename T>
struct MemoryPointer {
typedef decltype(nullptr) nullptr_t;
public:
MemoryPointer()
: uMemory({ 0 })
{}
MemoryPointer(const MemoryPointer &other) = delete;
MemoryPointer &MemoryPointer::operator=(const MemoryPointer &other) = delete;
MemoryPointer &MemoryPointer::operator=(nullptr_t) noexcept {
free();
uMemory = { 0 };
return (*this);
}
MemoryPointer(MemoryPointer &&other) noexcept {
uMemory = other.uMemory;
other.uMemory = { 0 };
}
MemoryPointer& MemoryPointer::operator=(MemoryPointer &&other) noexcept {
if (this != &other) {
free();
uMemory = other.uMemory;
other.uMemory = { 0 };
}
return (*this);
}
~MemoryPointer() {
free();
}
inline T *data() const {
return static_cast<T *>(uMemory.pointer);
}
inline T *operator->() const {
return data();
}
inline T &operator*() const {
return *data();
}
inline operator T*() const {
return data();
}
inline operator bool() const noexcept {
return data() != nullptr;
}
inline bool isNull() const {
return uMemory.pointer == NULL;
}
private:
void free() {
if (uMemory.alloced) {
::free(reinterpret_cast<void *>(uMemory.pointer));
uMemory = { 0 };
}
}
private:
union MemoryUnion {
quint64 value;
struct {
quint64 alloced : 1;
quint64 pointer : 48;
};
};
MemoryUnion uMemory;
};
template <class T>
inline bool operator==(const T *o, const MemoryPointer<T> &p) {
return o == p.operator->();
}
template<class T>
inline bool operator==(const MemoryPointer<T> &p, const T *o) {
return p.operator->() == o;
}
template <class T>
inline bool operator==(T *o, const MemoryPointer<T> &p) {
return o == p.operator->();
}
template<class T>
inline bool operator==(const MemoryPointer<T> &p, T *o) {
return p.operator->() == o;
}
template<class T>
inline bool operator==(const MemoryPointer<T> &lhs, const MemoryPointer<T> &rhs) {
return lhs.operator->() == rhs.operator->();
}
template <class T>
inline bool operator!=(const T *o, const MemoryPointer<T> &p) {
return o != p.operator->();
}
template<class T>
inline bool operator!= (const MemoryPointer<T> &p, const T *o) {
return p.operator->() != o;
}
template <class T>
inline bool operator!=(T *o, const MemoryPointer<T> &p) {
return o != p.operator->();
}
template<class T>
inline bool operator!= (const MemoryPointer<T> &p, T *o) {
return p.operator->() != o;
}
template<class T>
inline bool operator!= (const MemoryPointer<T> &lhs, const MemoryPointer<T> &rhs) {
return lhs.operator->() != rhs.operator->();
}
#endif // MEMORYPOINTER_H

View File

@@ -2922,6 +2922,12 @@ int ssh_channel_read_timeout(ssh_channel channel,
timeout_ms, timeout_ms,
ssh_channel_read_termination, ssh_channel_read_termination,
&ctx); &ctx);
if (rc == SSH_AGAIN && ssh_is_blocking(session)) {
ssh_set_error(session, SSH_FATAL, "Handle packets timeout.");
return rc;
}
if (rc == SSH_ERROR){ if (rc == SSH_ERROR){
return rc; return rc;
} }