diff --git a/Cargo.toml b/Cargo.toml index fd28344..f860cbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ming-wm" -version = "1.0.0-beta.1" +version = "1.0.0" repository = "https://github.com/stjet/ming-wm" license = "GPL-3.0-or-later" edition = "2021" @@ -20,7 +20,7 @@ ming-wm-lib = { path = "ming-wm-lib" } blake2 = { version = "0.10.6", default-features = false } linux = { path = "linux" } termion = { version = "4.0.3", optional = true } -rodio = { version = "0.19.0", optional = true } +rodio = { version = "0.19.0", default-features = false, features = [ "flac", "mp3", "symphonia-vorbis", "wav" ], optional = true } rand = { version = "0.9.0", default-features = false, features = [ "small_rng" ], optional = true } id3 = { version = "1.10.0", optional = true } mp4ameta = { version = "0.11.0", optional = true } diff --git a/README.md b/README.md index 3045183..5bdefb7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Ming-wm is a keyboard-based, retro-themed window manager for Linux. It is single-threaded, and is neither for Wayland or the X Window System - it writes directly to the framebuffer. Inspirations include i3, Haiku, SerenityOS, and Windows98, and it is a conceptual successor to the previous [mingde](https://github.com/stjet/mingde) and [ming-os](https://github.com/stjet/ming-os). +Ming-wm is a keyboard-based, retro-themed window manager for Linux. It is neither for Wayland or the X Window System - it writes directly to the framebuffer. Inspirations include i3, Haiku, SerenityOS, and Windows98, and it is a conceptual successor to the previous [mingde](https://github.com/stjet/mingde) and [ming-os](https://github.com/stjet/ming-os). ![example 1](/docs/images/ws1.png) ![example 2](/docs/images/ws3.png) @@ -49,7 +49,7 @@ Usage for most of the included windows and window-likes are included in `docs/wi ## Running on Mobile Linux -Running with an onscreen keyboard. The framebuffer may not be redrawn to the screen without a (real) key press. The volume down button seems to work. +Running with an onscreen keyboard. The framebuffer may not be redrawn to the screen without a (real) key press. The volume down button seems to work. If someone knows why this is the case, and/or how to fix this, please let me know. `evtest` needs to be installed. Currently, the input device is assumed to be at `/dev/first-touchscreen`. @@ -73,7 +73,7 @@ See [/docs/philosophy.md](/docs/philosophy.md) for some hopefully interesting ra Windows (may be called apps in other window managers) can be developed in any language, though it is easiest to do so in Rust because the `ming-wm-lib` crate can be used. -See [koxinga](https://github.com/stjet/koxinga) or `src/bin` for examples. The `docs` directory includes a [brief introduction to writing windows](docs/system/writing_windows.md). [incomplete] documentation on the architecture of ming-wm. +See [koxinga](https://github.com/stjet/koxinga) or `src/bin` for examples. The `docs` directory includes a [brief introduction to writing windows](docs/system/writing_windows.md), and (incomplete) documentation on the workings of ming-wm. ## Security diff --git a/bmps/shippori-mincho/y0.bmp b/bmps/shippori-mincho/y0.bmp new file mode 100644 index 0000000..a9c0ee6 Binary files /dev/null and b/bmps/shippori-mincho/y0.bmp differ diff --git a/bmps/shippori-mincho/ア2.bmp b/bmps/shippori-mincho/ア2.bmp new file mode 100644 index 0000000..1703ab0 Binary files /dev/null and b/bmps/shippori-mincho/ア2.bmp differ diff --git a/bmps/shippori-mincho/イ2.bmp b/bmps/shippori-mincho/イ2.bmp new file mode 100644 index 0000000..f8a2cda Binary files /dev/null and b/bmps/shippori-mincho/イ2.bmp differ diff --git a/bmps/shippori-mincho/ウ1.bmp b/bmps/shippori-mincho/ウ1.bmp new file mode 100644 index 0000000..4a5aa57 Binary files /dev/null and b/bmps/shippori-mincho/ウ1.bmp differ diff --git a/bmps/shippori-mincho/エ3.bmp b/bmps/shippori-mincho/エ3.bmp new file mode 100644 index 0000000..a268481 Binary files /dev/null and b/bmps/shippori-mincho/エ3.bmp differ diff --git a/bmps/shippori-mincho/オ2.bmp b/bmps/shippori-mincho/オ2.bmp new file mode 100644 index 0000000..9de1907 Binary files /dev/null and b/bmps/shippori-mincho/オ2.bmp differ diff --git a/bmps/shippori-mincho/カ2.bmp b/bmps/shippori-mincho/カ2.bmp new file mode 100644 index 0000000..96c7ab9 Binary files /dev/null and b/bmps/shippori-mincho/カ2.bmp differ diff --git a/bmps/shippori-mincho/キ2.bmp b/bmps/shippori-mincho/キ2.bmp new file mode 100644 index 0000000..79ba105 Binary files /dev/null and b/bmps/shippori-mincho/キ2.bmp differ diff --git a/bmps/shippori-mincho/ク3.bmp b/bmps/shippori-mincho/ク3.bmp new file mode 100644 index 0000000..1bf01db Binary files /dev/null and b/bmps/shippori-mincho/ク3.bmp differ diff --git a/bmps/shippori-mincho/ケ3.bmp b/bmps/shippori-mincho/ケ3.bmp new file mode 100644 index 0000000..7c1570a Binary files /dev/null and b/bmps/shippori-mincho/ケ3.bmp differ diff --git a/bmps/shippori-mincho/コ3.bmp b/bmps/shippori-mincho/コ3.bmp new file mode 100644 index 0000000..ea99e97 Binary files /dev/null and b/bmps/shippori-mincho/コ3.bmp differ diff --git a/bmps/shippori-mincho/サ1.bmp b/bmps/shippori-mincho/サ1.bmp new file mode 100644 index 0000000..1448d1b Binary files /dev/null and b/bmps/shippori-mincho/サ1.bmp differ diff --git a/bmps/shippori-mincho/シ3.bmp b/bmps/shippori-mincho/シ3.bmp new file mode 100644 index 0000000..27897c1 Binary files /dev/null and b/bmps/shippori-mincho/シ3.bmp differ diff --git a/bmps/shippori-mincho/ス4.bmp b/bmps/shippori-mincho/ス4.bmp new file mode 100644 index 0000000..8d801d1 Binary files /dev/null and b/bmps/shippori-mincho/ス4.bmp differ diff --git a/bmps/shippori-mincho/セ4.bmp b/bmps/shippori-mincho/セ4.bmp new file mode 100644 index 0000000..103b0cb Binary files /dev/null and b/bmps/shippori-mincho/セ4.bmp differ diff --git a/bmps/shippori-mincho/ソ0.bmp b/bmps/shippori-mincho/ソ0.bmp new file mode 100644 index 0000000..3676c7b Binary files /dev/null and b/bmps/shippori-mincho/ソ0.bmp differ diff --git a/bmps/shippori-mincho/タ2.bmp b/bmps/shippori-mincho/タ2.bmp new file mode 100644 index 0000000..b1dc0b5 Binary files /dev/null and b/bmps/shippori-mincho/タ2.bmp differ diff --git a/bmps/shippori-mincho/チ2.bmp b/bmps/shippori-mincho/チ2.bmp new file mode 100644 index 0000000..e554720 Binary files /dev/null and b/bmps/shippori-mincho/チ2.bmp differ diff --git a/bmps/shippori-mincho/ツ3.bmp b/bmps/shippori-mincho/ツ3.bmp new file mode 100644 index 0000000..35dd0ed Binary files /dev/null and b/bmps/shippori-mincho/ツ3.bmp differ diff --git a/bmps/shippori-mincho/テ1.bmp b/bmps/shippori-mincho/テ1.bmp new file mode 100644 index 0000000..a9ece7f Binary files /dev/null and b/bmps/shippori-mincho/テ1.bmp differ diff --git a/bmps/shippori-mincho/ト1.bmp b/bmps/shippori-mincho/ト1.bmp new file mode 100644 index 0000000..45a5380 Binary files /dev/null and b/bmps/shippori-mincho/ト1.bmp differ diff --git a/bmps/shippori-mincho/ナ1.bmp b/bmps/shippori-mincho/ナ1.bmp new file mode 100644 index 0000000..6d4c614 Binary files /dev/null and b/bmps/shippori-mincho/ナ1.bmp differ diff --git a/bmps/shippori-mincho/ニ3.bmp b/bmps/shippori-mincho/ニ3.bmp new file mode 100644 index 0000000..e88e4f2 Binary files /dev/null and b/bmps/shippori-mincho/ニ3.bmp differ diff --git a/bmps/shippori-mincho/ヌ4.bmp b/bmps/shippori-mincho/ヌ4.bmp new file mode 100644 index 0000000..af8e295 Binary files /dev/null and b/bmps/shippori-mincho/ヌ4.bmp differ diff --git a/bmps/shippori-mincho/ネ0.bmp b/bmps/shippori-mincho/ネ0.bmp new file mode 100644 index 0000000..f16a9c6 Binary files /dev/null and b/bmps/shippori-mincho/ネ0.bmp differ diff --git a/bmps/shippori-mincho/ノ3.bmp b/bmps/shippori-mincho/ノ3.bmp new file mode 100644 index 0000000..76f23b4 Binary files /dev/null and b/bmps/shippori-mincho/ノ3.bmp differ diff --git a/bmps/shippori-mincho/ハ7.bmp b/bmps/shippori-mincho/ハ7.bmp new file mode 100644 index 0000000..89b3743 Binary files /dev/null and b/bmps/shippori-mincho/ハ7.bmp differ diff --git a/bmps/shippori-mincho/ヒ3.bmp b/bmps/shippori-mincho/ヒ3.bmp new file mode 100644 index 0000000..a407f4d Binary files /dev/null and b/bmps/shippori-mincho/ヒ3.bmp differ diff --git a/bmps/shippori-mincho/フ3.bmp b/bmps/shippori-mincho/フ3.bmp new file mode 100644 index 0000000..b582568 Binary files /dev/null and b/bmps/shippori-mincho/フ3.bmp differ diff --git a/bmps/shippori-mincho/ヘ7.bmp b/bmps/shippori-mincho/ヘ7.bmp new file mode 100644 index 0000000..b91a6d5 Binary files /dev/null and b/bmps/shippori-mincho/ヘ7.bmp differ diff --git a/bmps/shippori-mincho/ホ2.bmp b/bmps/shippori-mincho/ホ2.bmp new file mode 100644 index 0000000..16051ae Binary files /dev/null and b/bmps/shippori-mincho/ホ2.bmp differ diff --git a/bmps/shippori-mincho/マ6.bmp b/bmps/shippori-mincho/マ6.bmp new file mode 100644 index 0000000..f002890 Binary files /dev/null and b/bmps/shippori-mincho/マ6.bmp differ diff --git a/bmps/shippori-mincho/ミ2.bmp b/bmps/shippori-mincho/ミ2.bmp new file mode 100644 index 0000000..931ea58 Binary files /dev/null and b/bmps/shippori-mincho/ミ2.bmp differ diff --git a/bmps/shippori-mincho/ム4.bmp b/bmps/shippori-mincho/ム4.bmp new file mode 100644 index 0000000..c4f47f8 Binary files /dev/null and b/bmps/shippori-mincho/ム4.bmp differ diff --git a/bmps/shippori-mincho/メ2.bmp b/bmps/shippori-mincho/メ2.bmp new file mode 100644 index 0000000..6eedcc5 Binary files /dev/null and b/bmps/shippori-mincho/メ2.bmp differ diff --git a/bmps/shippori-mincho/モ3.bmp b/bmps/shippori-mincho/モ3.bmp new file mode 100644 index 0000000..d486787 Binary files /dev/null and b/bmps/shippori-mincho/モ3.bmp differ diff --git a/bmps/shippori-mincho/ヤ1.bmp b/bmps/shippori-mincho/ヤ1.bmp new file mode 100644 index 0000000..5d60bbc Binary files /dev/null and b/bmps/shippori-mincho/ヤ1.bmp differ diff --git a/bmps/shippori-mincho/ユ6.bmp b/bmps/shippori-mincho/ユ6.bmp new file mode 100644 index 0000000..d560b0b Binary files /dev/null and b/bmps/shippori-mincho/ユ6.bmp differ diff --git a/bmps/shippori-mincho/ヨ5.bmp b/bmps/shippori-mincho/ヨ5.bmp new file mode 100644 index 0000000..2a7bc05 Binary files /dev/null and b/bmps/shippori-mincho/ヨ5.bmp differ diff --git a/bmps/shippori-mincho/ラ1.bmp b/bmps/shippori-mincho/ラ1.bmp new file mode 100644 index 0000000..460672c Binary files /dev/null and b/bmps/shippori-mincho/ラ1.bmp differ diff --git a/bmps/shippori-mincho/リ1.bmp b/bmps/shippori-mincho/リ1.bmp new file mode 100644 index 0000000..c276ff0 Binary files /dev/null and b/bmps/shippori-mincho/リ1.bmp differ diff --git a/bmps/shippori-mincho/ル4.bmp b/bmps/shippori-mincho/ル4.bmp new file mode 100644 index 0000000..32dacf7 Binary files /dev/null and b/bmps/shippori-mincho/ル4.bmp differ diff --git a/bmps/shippori-mincho/レ5.bmp b/bmps/shippori-mincho/レ5.bmp new file mode 100644 index 0000000..726d127 Binary files /dev/null and b/bmps/shippori-mincho/レ5.bmp differ diff --git a/bmps/shippori-mincho/ロ5.bmp b/bmps/shippori-mincho/ロ5.bmp new file mode 100644 index 0000000..a4cf227 Binary files /dev/null and b/bmps/shippori-mincho/ロ5.bmp differ diff --git a/bmps/shippori-mincho/ワ2.bmp b/bmps/shippori-mincho/ワ2.bmp new file mode 100644 index 0000000..c1e54db Binary files /dev/null and b/bmps/shippori-mincho/ワ2.bmp differ diff --git a/bmps/shippori-mincho/ヲ1.bmp b/bmps/shippori-mincho/ヲ1.bmp new file mode 100644 index 0000000..893a39a Binary files /dev/null and b/bmps/shippori-mincho/ヲ1.bmp differ diff --git a/bmps/shippori-mincho/ン3.bmp b/bmps/shippori-mincho/ン3.bmp new file mode 100644 index 0000000..4a8207b Binary files /dev/null and b/bmps/shippori-mincho/ン3.bmp differ diff --git a/bmps/shippori-mincho/不0.bmp b/bmps/shippori-mincho/不0.bmp new file mode 100644 index 0000000..33049eb Binary files /dev/null and b/bmps/shippori-mincho/不0.bmp differ diff --git a/bmps/shippori-mincho/会0.bmp b/bmps/shippori-mincho/会0.bmp new file mode 100644 index 0000000..da7385d Binary files /dev/null and b/bmps/shippori-mincho/会0.bmp differ diff --git a/bmps/shippori-mincho/作0.bmp b/bmps/shippori-mincho/作0.bmp new file mode 100644 index 0000000..13528a3 Binary files /dev/null and b/bmps/shippori-mincho/作0.bmp differ diff --git a/bmps/shippori-mincho/光0.bmp b/bmps/shippori-mincho/光0.bmp new file mode 100644 index 0000000..7a8a00b Binary files /dev/null and b/bmps/shippori-mincho/光0.bmp differ diff --git a/bmps/shippori-mincho/分0.bmp b/bmps/shippori-mincho/分0.bmp new file mode 100644 index 0000000..1d556bd Binary files /dev/null and b/bmps/shippori-mincho/分0.bmp differ diff --git a/bmps/shippori-mincho/勉0.bmp b/bmps/shippori-mincho/勉0.bmp new file mode 100644 index 0000000..92d5c8d Binary files /dev/null and b/bmps/shippori-mincho/勉0.bmp differ diff --git a/bmps/shippori-mincho/動0.bmp b/bmps/shippori-mincho/動0.bmp new file mode 100644 index 0000000..9f7ff5d Binary files /dev/null and b/bmps/shippori-mincho/動0.bmp differ diff --git a/bmps/shippori-mincho/園0.bmp b/bmps/shippori-mincho/園0.bmp new file mode 100644 index 0000000..85e6d4b Binary files /dev/null and b/bmps/shippori-mincho/園0.bmp differ diff --git a/bmps/shippori-mincho/夕0.bmp b/bmps/shippori-mincho/夕0.bmp new file mode 100644 index 0000000..e27ea63 Binary files /dev/null and b/bmps/shippori-mincho/夕0.bmp differ diff --git a/bmps/shippori-mincho/待0.bmp b/bmps/shippori-mincho/待0.bmp new file mode 100644 index 0000000..7b2ea94 Binary files /dev/null and b/bmps/shippori-mincho/待0.bmp differ diff --git a/bmps/shippori-mincho/悪0.bmp b/bmps/shippori-mincho/悪0.bmp new file mode 100644 index 0000000..91bad6e Binary files /dev/null and b/bmps/shippori-mincho/悪0.bmp differ diff --git a/bmps/shippori-mincho/昼1.bmp b/bmps/shippori-mincho/昼1.bmp new file mode 100644 index 0000000..092f593 Binary files /dev/null and b/bmps/shippori-mincho/昼1.bmp differ diff --git a/bmps/shippori-mincho/正1.bmp b/bmps/shippori-mincho/正1.bmp new file mode 100644 index 0000000..dca5400 Binary files /dev/null and b/bmps/shippori-mincho/正1.bmp differ diff --git a/bmps/shippori-mincho/消0.bmp b/bmps/shippori-mincho/消0.bmp new file mode 100644 index 0000000..59cab01 Binary files /dev/null and b/bmps/shippori-mincho/消0.bmp differ diff --git a/bmps/shippori-mincho/火0.bmp b/bmps/shippori-mincho/火0.bmp new file mode 100644 index 0000000..269e2ee Binary files /dev/null and b/bmps/shippori-mincho/火0.bmp differ diff --git a/bmps/shippori-mincho/物0.bmp b/bmps/shippori-mincho/物0.bmp new file mode 100644 index 0000000..c7cf1c0 Binary files /dev/null and b/bmps/shippori-mincho/物0.bmp differ diff --git a/bmps/shippori-mincho/番0.bmp b/bmps/shippori-mincho/番0.bmp new file mode 100644 index 0000000..ee61446 Binary files /dev/null and b/bmps/shippori-mincho/番0.bmp differ diff --git a/bmps/shippori-mincho/空0.bmp b/bmps/shippori-mincho/空0.bmp new file mode 100644 index 0000000..275368e Binary files /dev/null and b/bmps/shippori-mincho/空0.bmp differ diff --git a/bmps/shippori-mincho/街0.bmp b/bmps/shippori-mincho/街0.bmp new file mode 100644 index 0000000..31b8984 Binary files /dev/null and b/bmps/shippori-mincho/街0.bmp differ diff --git a/bmps/shippori-mincho/身0.bmp b/bmps/shippori-mincho/身0.bmp new file mode 100644 index 0000000..9d3cc9d Binary files /dev/null and b/bmps/shippori-mincho/身0.bmp differ diff --git a/bmps/shippori-mincho/辺1.bmp b/bmps/shippori-mincho/辺1.bmp new file mode 100644 index 0000000..bbd9586 Binary files /dev/null and b/bmps/shippori-mincho/辺1.bmp differ diff --git a/bmps/shippori-mincho/遊0.bmp b/bmps/shippori-mincho/遊0.bmp new file mode 100644 index 0000000..2c9e1f3 Binary files /dev/null and b/bmps/shippori-mincho/遊0.bmp differ diff --git a/bmps/shippori-mincho/違0.bmp b/bmps/shippori-mincho/違0.bmp new file mode 100644 index 0000000..d31edc2 Binary files /dev/null and b/bmps/shippori-mincho/違0.bmp differ diff --git a/bmps/shippori-mincho/鉄0.bmp b/bmps/shippori-mincho/鉄0.bmp new file mode 100644 index 0000000..29701fa Binary files /dev/null and b/bmps/shippori-mincho/鉄0.bmp differ diff --git a/bmps/shippori-mincho/風0.bmp b/bmps/shippori-mincho/風0.bmp new file mode 100644 index 0000000..3793db4 Binary files /dev/null and b/bmps/shippori-mincho/風0.bmp differ diff --git a/docs/system/README.md b/docs/system/README.md index ad3277c..7239d9f 100644 --- a/docs/system/README.md +++ b/docs/system/README.md @@ -104,9 +104,9 @@ Further documentation on specific window-likes can be found in `docs/window-like The window manager passes information about it's theme to all window-likes as a parameter to `draw`, so windows can have appropriate background colours, highlight colours, text colours, etc. -//can't change themes yet. in fact, no other themes yet +See the end of `docs/window-likes/desktop-background.md` for theme config information. ## Fonts / Text -// -//Japanese / Chinese characters can only be used for display, not input, as there is no CJK input system. yet. And these text inputs don't yet handle multi-byte input very gracefully +See `docs/system/fonts.md`. There is no Japanese input system... yet. + diff --git a/docs/window-likes/audio-player.md b/docs/window-likes/audio-player.md index 90bd51b..e0553ae 100644 --- a/docs/window-likes/audio-player.md +++ b/docs/window-likes/audio-player.md @@ -12,6 +12,8 @@ Type to write commands, backspace to delete last character, and enter to run com - `p `: Play audio files in `` or play the songs listed in the ``. Unless paths are absolute, they will be relative to the directory specified by the `b ` command - `a `: Same as `p` but appends to the end of the queue instead of clearing the current song and the queue +Tab completion is supported for the `` and `` arguments. + ## Playlists Example playlist file: diff --git a/docs/window-likes/malvim.md b/docs/window-likes/malvim.md index 1ff12bc..97b5a2e 100644 --- a/docs/window-likes/malvim.md +++ b/docs/window-likes/malvim.md @@ -1,4 +1,6 @@ -A text editor. Specifically, a subset of a vim. +A text/code editor. Specifically, a subset of vim. + +Funnily enough, that subset doesn't include the **vi**sual (ie, multi-line) capabilities of vim that the "vi" stands for. Perhaps it should be called "maled"? ## Usage @@ -6,11 +8,13 @@ It is probably best to read a Vim tutorial for the basics. All supportd keystrok ### Supported in Command-line Mode -- `e[dit]` -- `t[abe]`, `[tab]n`, `[tab]p` +- `e[dit] ` +- `t[abe] `, `[tab]n`, `[tab]p` - `q[uit]` - `w[rite]` +Tab completion is supported for the `` argument. + ### Supported in Normal Mode - `:` @@ -26,8 +30,9 @@ It is probably best to read a Vim tutorial for the basics. All supportd keystrok - `F` - `x` - `h`, `j`, `k`, `l` +- `h`, `j`, `k`, `l` - `0`, `^`, `$` ### Malvim Specific -In Command-line Mode, `autoindent` can be done to toggle auto-indenting (when making new line in Insert Mode [ie, by hitting Enter/Return], space indentation of the new line will be the same as the space indentation of the current line). +In Command-line Mode, `autoindent` can be done to toggle auto-indenting (when making new line in Insert Mode [ie, by hitting Enter/Return], space indentation of the new line will be the same as the space indentation of the current line). **Toggling on `autoindent` is highly recommended when editing code.** diff --git a/docs/window-likes/terminal.md b/docs/window-likes/terminal.md index e36c655..709a3d3 100644 --- a/docs/window-likes/terminal.md +++ b/docs/window-likes/terminal.md @@ -8,13 +8,17 @@ The terminal starts off in INPUT mode, which allows entering commands to run. If In INPUT mode, commands can be freely typed. There are a few special control sequences: -- `ctrl+p`: Brings up the last run command to the command input -- `ctrl+n`: Clears the command input +- `ctrl+p`: Equivalent to the up arrow in most terminals. Brings up the previous command in the command history, and so on. +- `ctrl+n`: Equivalent to the down arrow in most terminals. Either clears the current input if not in a previous command, else brings up the next command in the command history. + +Tab completion is also supported, though only for file/directory paths. Once a command is entered, hit 'enter' to execute it. The terminal will change into "RUNNING" mode. In this mode, clicking any key except for 'i' will result in the terminal writing the current output of the running command to the window (`ctrl+c` will force the process to exit). It will also check if the command has exited, in which case the INPUT mode is returned to. Clicking the 'i' key will change the terminal to "STDIN" mode. In STDIN mode, any keys typed followed by the 'enter' key will send those keys to the command's STDIN, if it is still running. To escape STDIN mode, use the `esc` key. +ANSI escape codes are currently not supported, and are stripped. + ### Sudo To get sudo to read from stdin, the `-S` option will need to be used (eg, `sudo -S ls`). Then switch to STDIN mode, type in the password and hit enter. @@ -23,3 +27,6 @@ To get sudo to read from stdin, the `-S` option will need to be used (eg, `sudo This window-like supports the paste [shortcut](../system/shortcuts.md) (`Alt+P`) if in INPUT or STDIN mode. +## Notes + +Some commands like `git diff` don't quite work well yet. Also, some command outputs are very long, but the terminal doesn't really support scrolling. Instead, redirect the output of those commands to a file and read it in Malvim (eg `git diff > diff.txt`). diff --git a/install b/install index 8833815..4bb0f57 100755 --- a/install +++ b/install @@ -1,8 +1,13 @@ #!/bin/sh rm -rf /usr/local/bin/ming_bmps cp -r ./bmps /usr/local/bin/ming_bmps +rm -rf /usr/local/bin/ming_bmps/nimbus-roman/*.bmp +rm -rf /usr/local/bin/ming_bmps/nimbus-romano/*.bmp +rm -rf /usr/local/bin/ming_bmps/shippori-mincho/*.bmp +rm /usr/local/bin/ming_bmps/*1440x842.bmp rm -rf /usr/local/bin/ming_docs cp -r ./docs /usr/local/bin/ming_docs +rm -rf /usr/local/bin/ming_docs/images cp ./target/release/ming /usr/local/bin/ming cp ./target/release/mingUtils_Terminal /usr/local/bin/mingUtils_Terminal cp ./target/release/mingGames_Reversi /usr/local/bin/mingGames_Reversi diff --git a/local-install b/local-install index dbda156..f121c34 100755 --- a/local-install +++ b/local-install @@ -1,8 +1,13 @@ #!/bin/sh rm -rf ~/.local/bin/ming_bmps cp -r ./bmps ~/.local/bin/ming_bmps +rm -rf ~/.local/bin/ming_bmps/nimbus-roman/*.bmp +rm -rf ~/.local/bin/ming_bmps/nimbus-romano/*.bmp +rm -rf ~/.local/bin/ming_bmps/shippori-mincho/*.bmp +rm ~/.local/bin/ming_bmps/*1440x842.bmp rm -rf ~/.local/bin/ming_docs cp -r ./docs ~/.local/bin/ming_docs +rm -rf ~/.local/bin/ming_docs/images cp ./target/release/ming ~/.local/bin/ming cp ./target/release/mingUtils_Terminal ~/.local/bin/mingUtils_Terminal cp ./target/release/mingGames_Reversi ~/.local/bin/mingGames_Reversi diff --git a/ming-wm-lib/Cargo.toml b/ming-wm-lib/Cargo.toml index e74b738..155a3c7 100644 --- a/ming-wm-lib/Cargo.toml +++ b/ming-wm-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ming-wm-lib" -version = "0.1.3" +version = "0.1.4" repository = "https://github.com/stjet/ming-wm" description = "library for building windows for ming-wm in rust" license = "GPL-3.0-or-later" diff --git a/ming-wm-lib/src/utils.rs b/ming-wm-lib/src/utils.rs index 7ba9495..1e2aa20 100644 --- a/ming-wm-lib/src/utils.rs +++ b/ming-wm-lib/src/utils.rs @@ -1,4 +1,5 @@ use std::path::PathBuf; +use std::fs::read_dir; use crate::framebuffer_types::{ Dimensions, Point }; @@ -80,6 +81,10 @@ pub fn calc_new_cursor_pos(cursor_pos: usize, new_length: usize) -> usize { pub fn concat_paths(current_path: &str, add_path: &str) -> Result { let mut new_path = PathBuf::from(current_path); + //if current_path is a file, automatically uses it's parent (a directory) + if new_path.is_file() { + new_path = new_path.parent().unwrap().to_path_buf(); + } if add_path.starts_with("/") { //absolute path new_path = PathBuf::from(add_path); @@ -156,3 +161,36 @@ pub fn get_rest_of_split(split: &mut dyn Iterator, sep: Option<&str rest } +pub fn path_autocomplete(current_path: &str, partial_path: &str) -> Option { + if let Ok(new_path) = concat_paths(current_path, &partial_path) { + let partial_name; + let parent; + if partial_path.ends_with("/") { + partial_name = "".to_string(); + parent = new_path.as_path(); + } else { + //this is just silly + partial_name = new_path.clone().file_name().unwrap().to_os_string().to_string_lossy().to_string(); + parent = new_path.parent().unwrap(); + }; + if let Ok(entries) = read_dir(parent) { + for entry in entries { + let entry_path = entry.unwrap().path(); + let name = entry_path.file_name().unwrap().to_os_string().to_string_lossy().to_string(); + if name.starts_with(&partial_name) { + let add = name[partial_name.len()..].to_string(); + let add_len = add.len(); + return Some(add + if entry_path.is_dir() && add_len > 0 { + "/" + } else { + "" + }); + } + } + } + None + } else { + None + } +} + diff --git a/src/bin/audio_player.rs b/src/bin/audio_player.rs index 1abb733..e940b98 100644 --- a/src/bin/audio_player.rs +++ b/src/bin/audio_player.rs @@ -17,7 +17,7 @@ use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLik use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse }; use ming_wm_lib::framebuffer_types::Dimensions; use ming_wm_lib::themes::ThemeInfo; -use ming_wm_lib::utils::{ concat_paths, format_seconds, Substring }; +use ming_wm_lib::utils::{ concat_paths, path_autocomplete, format_seconds, Substring }; use ming_wm_lib::dirs::home; use ming_wm_lib::ipc::listen; use ming_wm::fs::get_all_files; @@ -98,6 +98,18 @@ impl WindowLike for AudioPlayer { if self.command.len() > 0 { self.command = self.command.remove_last(); } + } else if key_press.key == '\t' { //tab + let mut parts = self.command.split(" "); + let parts_len = parts.clone().count(); + if parts_len == 2 { + if let Some(add) = path_autocomplete(&self.base_directory, parts.nth(1).unwrap()) { + self.command += &add; + } else { + return WindowMessageResponse::DoNothing; + } + } else { + return WindowMessageResponse::DoNothing; + } } else { self.command += &key_press.key.to_string(); } diff --git a/src/bin/malvim.rs b/src/bin/malvim.rs index 0b6ba5c..247df8d 100644 --- a/src/bin/malvim.rs +++ b/src/bin/malvim.rs @@ -10,6 +10,7 @@ use ming_wm_lib::framebuffer_types::Dimensions; use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType }; use ming_wm_lib::utils::{ calc_actual_lines, calc_new_cursor_pos, Substring }; use ming_wm_lib::dirs::home; +use ming_wm_lib::utils::path_autocomplete; use ming_wm_lib::ipc::listen; const MONO_WIDTH: u8 = 10; @@ -175,11 +176,17 @@ impl WindowLike for Malvim { let new_length = current_file.content[current_file.line_pos].chars().count(); current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); } else if key_press.key == 'w' { - //todo: currently doesn't work on a single space? let line = ¤t_file.content[current_file.line_pos]; - if line.len() > 0 { + let line_len = line.chars().count(); + if line_len > 0 && current_file.cursor_pos < line_len { //offset until space or eol - let offset = line.chars().skip(current_file.cursor_pos).position(|c| c == ' ').unwrap_or(line.chars().count() - current_file.cursor_pos); + let mut line_chars = line.chars().skip(current_file.cursor_pos).peekable(); + let current_char = line_chars.peek().unwrap().clone(); + let offset = line_chars.position(|c| if current_char == ' ' { + c != ' ' + } else { + c == ' ' + }).unwrap_or(line_len - current_file.cursor_pos); current_file.content[current_file.line_pos] = line.remove(current_file.cursor_pos, offset); let new_length = current_file.content[current_file.line_pos].chars().count(); current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); @@ -235,23 +242,23 @@ impl WindowLike for Malvim { } } } else if key_press.key == 'h' { - current_file.cursor_pos = current_file.cursor_pos.checked_sub(1).unwrap_or(0); + current_file.cursor_pos = current_file.cursor_pos.checked_sub(self.maybe_num.unwrap_or(1)).unwrap_or(0); changed = false; } else if key_press.key == 'j' || key_press.key == 'k' { if key_press.key == 'j' { - current_file.line_pos += 1; - if current_file.line_pos == current_file.content.len() { + current_file.line_pos += self.maybe_num.unwrap_or(1); + if current_file.line_pos >= current_file.content.len() { current_file.line_pos = current_file.content.len() - 1; } } else { - current_file.line_pos = current_file.line_pos.checked_sub(1).unwrap_or(0); + current_file.line_pos = current_file.line_pos.checked_sub(self.maybe_num.unwrap_or(1)).unwrap_or(0); } let new_length = current_file.content[current_file.line_pos].chars().count(); current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); changed = false; } else if key_press.key == 'l' { if current_length > 0 { - current_file.cursor_pos += 1; + current_file.cursor_pos += self.maybe_num.unwrap_or(1); let line_len = current_file.content[current_file.line_pos].chars().count(); if current_file.cursor_pos > line_len { current_file.cursor_pos = line_len; @@ -295,10 +302,10 @@ impl WindowLike for Malvim { } else { changed = false; } + //reset maybe_num if not num if !numbered && self.state != State::Maybeg { self.maybe_num = None; } - // } else if self.mode == Mode::Command { self.bottom_message = None; let command = self.command.clone().unwrap_or("".to_string()); @@ -306,6 +313,23 @@ impl WindowLike for Malvim { new = self.process_command(); self.command = None; self.mode = Mode::Normal; + } else if key_press.key == '\t' { //tab + let mut parts = command.split(" ").skip(1); + let parts_len = parts.clone().count(); + if parts_len == 1 { //caused one skipped + if let Some(second) = parts.next() { + let base_path = if self.files.len() > 0 { + //this is a file path, not a directory, + //but path_autocomplete's concat_path will sort it out for us + &self.files[self.current_file_index].path + } else { + &home().unwrap_or(PathBuf::from("/")).to_string_lossy().to_string() + }; + if let Some(add) = path_autocomplete(&base_path, second) { + self.command = Some(command + &add); + } + } + } } else if key_press.key == '𐘁' { //backspace if command.len() > 0 { self.command = Some(command[..command.len() - 1].to_string()); @@ -388,7 +412,7 @@ impl WindowLike for Malvim { theme_info.alt_secondary }; instructions.extend(vec![ - DrawInstructions::Rect([used_width, 2], [future_used_width, BAND_HEIGHT - 2], background), + DrawInstructions::Rect([used_width, 2], [future_used_width - used_width, BAND_HEIGHT - 2], background), DrawInstructions::Text([used_width + 2, 2], vec!["nimbus-romono".to_string()], if file_info.changed { "+ ".to_string() } else { String::new() } + &file_info.name, theme_info.alt_text, background, Some(0), Some(MONO_WIDTH)), ]); used_width = future_used_width; @@ -550,12 +574,12 @@ impl Malvim { } } else { //t(abe) - self.current_file_index += 1; if self.current_file_index == self.files.len() - 1 { self.files.push(file_info); } else { - self.files.insert(self.current_file_index, file_info); + self.files.insert(self.current_file_index + 1, file_info); } + self.current_file_index += 1; } return true; } else { @@ -577,15 +601,18 @@ impl Malvim { current_file.cursor_pos = 0; } } - } else if first == "w" || first == "write" { - let current_file = &self.files[self.current_file_index]; - let _ = write(¤t_file.path, ¤t_file.content.join("\n")); - self.files[self.current_file_index].changed = false; - self.bottom_message = Some("Written".to_string()); - } else if first == "q" || first == "quit" { - self.files.remove(self.current_file_index); - self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(0); - return true; + } else if first == "x" || first == "w" || first == "write" || first == "q" || first == "quit" { + if first == "x" || first == "w" || first == "write" { + let current_file = &self.files[self.current_file_index]; + let _ = write(¤t_file.path, ¤t_file.content.join("\n")); + self.files[self.current_file_index].changed = false; + self.bottom_message = Some("Written".to_string()); + } + if first == "x" || first == "q" || first == "quit" { + self.files.remove(self.current_file_index); + self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(0); + return true; + } } else if first == "p" || first == "tabp" { self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(self.files.len() - 1); return true; diff --git a/src/bin/terminal.rs b/src/bin/terminal.rs index e4e5e1f..f279654 100644 --- a/src/bin/terminal.rs +++ b/src/bin/terminal.rs @@ -7,7 +7,6 @@ use std::io::{ Read, Write }; use std::time::Duration; use std::path::PathBuf; use std::fmt; -use std::fs::read_dir; use pty_process::blocking; @@ -15,12 +14,10 @@ use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLik use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, ShortcutType }; use ming_wm_lib::framebuffer_types::Dimensions; use ming_wm_lib::themes::ThemeInfo; -use ming_wm_lib::utils::{ concat_paths, Substring }; +use ming_wm_lib::utils::{ concat_paths, path_autocomplete, Substring }; use ming_wm_lib::dirs::home; use ming_wm_lib::ipc::listen; -//todo: support copy and paste - const MONO_WIDTH: u8 = 10; const LINE_HEIGHT: usize = 15; const PADDING: usize = 4; @@ -83,7 +80,8 @@ pub struct Terminal { process_current_line: Vec, //bytes of line pty_outerr_rx: Option>, pty_in_tx: Option>, - last_command: Option, + history: Vec, + history_index: Option, } //for some reason key presses, then moving the window leaves the old window still there, behind it. weird @@ -114,39 +112,21 @@ impl WindowLike for Terminal { } } else if key_press.key == '𐘂' { //the enter key self.lines.push("$ ".to_string() + &self.current_input); - self.last_command = Some(self.current_input.clone()); + self.history.push(self.current_input.clone()); + self.history_index = None; self.mode = self.process_command(); self.current_input = String::new(); } else if key_press.key == '\t' { //tab //autocomplete assuming it's a file system path //...mostly working - let mut useless_tab = true; if self.current_input.len() > 0 { let partial_path = self.current_input.split(" ").last().unwrap(); - if let Ok(new_path) = concat_paths(&self.current_path, partial_path) { - let partial_name; - let parent; - if self.current_input.ends_with("/") { - partial_name = "".to_string(); - parent = new_path.as_path(); - } else { - //this is just silly - partial_name = new_path.clone().file_name().unwrap().to_os_string().to_string_lossy().to_string(); - parent = new_path.parent().unwrap(); - }; - for entry in read_dir(parent).unwrap() { - let name = entry.unwrap().path().file_name().unwrap().to_os_string().to_string_lossy().to_string(); - if name.starts_with(&partial_name) { - self.current_input += &name[partial_name.len()..]; - useless_tab = false; - break; - } - } + if let Some(add) = path_autocomplete(&self.current_path, partial_path) { + self.current_input += &add; + } else { + return WindowMessageResponse::DoNothing; } } - if useless_tab { - return WindowMessageResponse::DoNothing; - } } else { self.current_input += &key_press.key.to_string(); } @@ -229,12 +209,25 @@ impl WindowLike for Terminal { WindowMessageResponse::JustRedraw } else if self.mode == Mode::Input && (key_press.key == 'p' || key_press.key == 'n') { //only the last command is saved unlike other terminals. good enough for me - if key_press.key == 'p' && self.last_command.is_some() { - self.current_input = self.last_command.clone().unwrap(); + if key_press.key == 'p' && self.history.len() > 0 { + if let Some(history_index) = self.history_index { + if history_index > 0 { + self.history_index = Some(history_index - 1); + } + } else { + self.history_index = Some(self.history.len() - 1); + } + self.current_input = self.history[self.history_index.unwrap()].clone(); self.calc_actual_lines(); WindowMessageResponse::JustRedraw } else if key_press.key == 'n' { - self.current_input = String::new(); + if self.history_index.is_none() || self.history_index.unwrap() == self.history.len() - 1 { + self.history_index = None; + self.current_input = String::new(); + } else { + self.history_index = Some(self.history_index.unwrap() + 1); + self.current_input = self.history[self.history_index.unwrap()].clone(); + } self.calc_actual_lines(); WindowMessageResponse::JustRedraw } else { diff --git a/src/essential/help.rs b/src/essential/help.rs index fba8577..abfb3c3 100644 --- a/src/essential/help.rs +++ b/src/essential/help.rs @@ -23,7 +23,12 @@ impl WindowLike for Help { match message { WindowMessage::Init(dimensions) => { self.dimensions = dimensions; - self.paragraph = Some(Box::new(Paragraph::new("help".to_string(), [2, 22], [self.dimensions[0] - 4, self.dimensions[1] - 24], "Press the 'h' and 'l' keys to read the different help pages".to_string(), ()))); + let first_content = if self.files.len() > 0 { + read_to_string(self.files[0].clone()).unwrap() + } else { + String::new() + }; + self.paragraph = Some(Box::new(Paragraph::new("help".to_string(), [2, 22], [self.dimensions[0] - 4, self.dimensions[1] - 24], "Press the 'h' and 'l' keys to read the different help pages".to_string() + &first_content, ()))); WindowMessageResponse::JustRedraw }, WindowMessage::KeyPress(key_press) => { @@ -97,4 +102,3 @@ impl Help { } } } - diff --git a/src/fs.rs b/src/fs.rs index d2706fd..2b9e0c5 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -30,8 +30,8 @@ pub fn get_font_char_from_fonts(fonts: &[String], c: char) -> (char, Vec } } let p = dirs::exe_dir(Some(&("ming_bmps/".to_string() + &fonts[0]))).to_string_lossy().to_string(); - //so a ? char must be in every font - get_font_char(&p, '?').unwrap() + //so a ? char should be in every font. otherwise will just return blank + get_font_char(&p, '?').unwrap_or(('?', vec![vec![0]], 0)) } pub fn get_all_files(dir: PathBuf) -> Vec {