v1.0.0: tab path autocomplete, malvim features, terminal history
various fixes, docs, some kanji and romaji font chars
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ming-wm"
|
name = "ming-wm"
|
||||||
version = "1.0.0-beta.1"
|
version = "1.0.0"
|
||||||
repository = "https://github.com/stjet/ming-wm"
|
repository = "https://github.com/stjet/ming-wm"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@@ -20,7 +20,7 @@ ming-wm-lib = { path = "ming-wm-lib" }
|
|||||||
blake2 = { version = "0.10.6", default-features = false }
|
blake2 = { version = "0.10.6", default-features = false }
|
||||||
linux = { path = "linux" }
|
linux = { path = "linux" }
|
||||||
termion = { version = "4.0.3", optional = true }
|
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 }
|
rand = { version = "0.9.0", default-features = false, features = [ "small_rng" ], optional = true }
|
||||||
id3 = { version = "1.10.0", optional = true }
|
id3 = { version = "1.10.0", optional = true }
|
||||||
mp4ameta = { version = "0.11.0", optional = true }
|
mp4ameta = { version = "0.11.0", optional = true }
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
@@ -49,7 +49,7 @@ Usage for most of the included windows and window-likes are included in `docs/wi
|
|||||||
|
|
||||||
## Running on Mobile Linux
|
## 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`.
|
`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.
|
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
|
## Security
|
||||||
|
|
||||||
|
|||||||
BIN
bmps/shippori-mincho/y0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/ア2.bmp
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
bmps/shippori-mincho/イ2.bmp
Normal file
|
After Width: | Height: | Size: 334 B |
BIN
bmps/shippori-mincho/ウ1.bmp
Normal file
|
After Width: | Height: | Size: 406 B |
BIN
bmps/shippori-mincho/エ3.bmp
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
bmps/shippori-mincho/オ2.bmp
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
bmps/shippori-mincho/カ2.bmp
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
bmps/shippori-mincho/キ2.bmp
Normal file
|
After Width: | Height: | Size: 454 B |
BIN
bmps/shippori-mincho/ク3.bmp
Normal file
|
After Width: | Height: | Size: 378 B |
BIN
bmps/shippori-mincho/ケ3.bmp
Normal file
|
After Width: | Height: | Size: 378 B |
BIN
bmps/shippori-mincho/コ3.bmp
Normal file
|
After Width: | Height: | Size: 246 B |
BIN
bmps/shippori-mincho/サ1.bmp
Normal file
|
After Width: | Height: | Size: 538 B |
BIN
bmps/shippori-mincho/シ3.bmp
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
bmps/shippori-mincho/ス4.bmp
Normal file
|
After Width: | Height: | Size: 342 B |
BIN
bmps/shippori-mincho/セ4.bmp
Normal file
|
After Width: | Height: | Size: 342 B |
BIN
bmps/shippori-mincho/ソ0.bmp
Normal file
|
After Width: | Height: | Size: 342 B |
BIN
bmps/shippori-mincho/タ2.bmp
Normal file
|
After Width: | Height: | Size: 454 B |
BIN
bmps/shippori-mincho/チ2.bmp
Normal file
|
After Width: | Height: | Size: 454 B |
BIN
bmps/shippori-mincho/ツ3.bmp
Normal file
|
After Width: | Height: | Size: 342 B |
BIN
bmps/shippori-mincho/テ1.bmp
Normal file
|
After Width: | Height: | Size: 450 B |
BIN
bmps/shippori-mincho/ト1.bmp
Normal file
|
After Width: | Height: | Size: 274 B |
BIN
bmps/shippori-mincho/ナ1.bmp
Normal file
|
After Width: | Height: | Size: 538 B |
BIN
bmps/shippori-mincho/ニ3.bmp
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
bmps/shippori-mincho/ヌ4.bmp
Normal file
|
After Width: | Height: | Size: 374 B |
BIN
bmps/shippori-mincho/ネ0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/ノ3.bmp
Normal file
|
After Width: | Height: | Size: 342 B |
BIN
bmps/shippori-mincho/ハ7.bmp
Normal file
|
After Width: | Height: | Size: 294 B |
BIN
bmps/shippori-mincho/ヒ3.bmp
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
bmps/shippori-mincho/フ3.bmp
Normal file
|
After Width: | Height: | Size: 378 B |
BIN
bmps/shippori-mincho/ヘ7.bmp
Normal file
|
After Width: | Height: | Size: 294 B |
BIN
bmps/shippori-mincho/ホ2.bmp
Normal file
|
After Width: | Height: | Size: 494 B |
BIN
bmps/shippori-mincho/マ6.bmp
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
bmps/shippori-mincho/ミ2.bmp
Normal file
|
After Width: | Height: | Size: 334 B |
BIN
bmps/shippori-mincho/ム4.bmp
Normal file
|
After Width: | Height: | Size: 342 B |
BIN
bmps/shippori-mincho/メ2.bmp
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
bmps/shippori-mincho/モ3.bmp
Normal file
|
After Width: | Height: | Size: 450 B |
BIN
bmps/shippori-mincho/ヤ1.bmp
Normal file
|
After Width: | Height: | Size: 538 B |
BIN
bmps/shippori-mincho/ユ6.bmp
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
bmps/shippori-mincho/ヨ5.bmp
Normal file
|
After Width: | Height: | Size: 278 B |
BIN
bmps/shippori-mincho/ラ1.bmp
Normal file
|
After Width: | Height: | Size: 450 B |
BIN
bmps/shippori-mincho/リ1.bmp
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
bmps/shippori-mincho/ル4.bmp
Normal file
|
After Width: | Height: | Size: 470 B |
BIN
bmps/shippori-mincho/レ5.bmp
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
bmps/shippori-mincho/ロ5.bmp
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
bmps/shippori-mincho/ワ2.bmp
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
bmps/shippori-mincho/ヲ1.bmp
Normal file
|
After Width: | Height: | Size: 450 B |
BIN
bmps/shippori-mincho/ン3.bmp
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
bmps/shippori-mincho/不0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/会0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/作0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/光0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/分0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/勉0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/動0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/園0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/夕0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/待0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/悪0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/昼1.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/正1.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/消0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/火0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/物0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/番0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/空0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/街0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/身0.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/辺1.bmp
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
bmps/shippori-mincho/遊0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/違0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/鉄0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
BIN
bmps/shippori-mincho/風0.bmp
Normal file
|
After Width: | Height: | Size: 630 B |
@@ -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.
|
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
|
## Fonts / Text
|
||||||
|
|
||||||
//
|
See `docs/system/fonts.md`. There is no Japanese input system... yet.
|
||||||
//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
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ Type to write commands, backspace to delete last character, and enter to run com
|
|||||||
- `p <dir / playlist file>`: Play audio files in `<dir>` or play the songs listed in the `<playlist file>`. Unless paths are absolute, they will be relative to the directory specified by the `b <dir>` command
|
- `p <dir / playlist file>`: Play audio files in `<dir>` or play the songs listed in the `<playlist file>`. Unless paths are absolute, they will be relative to the directory specified by the `b <dir>` command
|
||||||
- `a <dir / playlist file>`: Same as `p` but appends to the end of the queue instead of clearing the current song and the queue
|
- `a <dir / playlist file>`: 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 `<dir>` and `<dir / playlist file>` arguments.
|
||||||
|
|
||||||
## Playlists
|
## Playlists
|
||||||
|
|
||||||
Example playlist file:
|
Example playlist file:
|
||||||
|
|||||||
@@ -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
|
## 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
|
### Supported in Command-line Mode
|
||||||
|
|
||||||
- `e[dit]`
|
- `e[dit] <file>`
|
||||||
- `t[abe]`, `[tab]n`, `[tab]p`
|
- `t[abe] <file>`, `[tab]n`, `[tab]p`
|
||||||
- `q[uit]`
|
- `q[uit]`
|
||||||
- `w[rite]`
|
- `w[rite]`
|
||||||
|
|
||||||
|
Tab completion is supported for the `<file>` argument.
|
||||||
|
|
||||||
### Supported in Normal Mode
|
### Supported in Normal Mode
|
||||||
|
|
||||||
- `:`
|
- `:`
|
||||||
@@ -26,8 +30,9 @@ It is probably best to read a Vim tutorial for the basics. All supportd keystrok
|
|||||||
- `F<char>`
|
- `F<char>`
|
||||||
- `x`
|
- `x`
|
||||||
- `h`, `j`, `k`, `l`
|
- `h`, `j`, `k`, `l`
|
||||||
|
- `<num>h`, `<num>j`, `<num>k`, `<num>l`
|
||||||
- `0`, `^`, `$`
|
- `0`, `^`, `$`
|
||||||
|
|
||||||
### Malvim Specific
|
### 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.**
|
||||||
|
|||||||
@@ -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:
|
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+p`: Equivalent to the up arrow in most terminals. Brings up the previous command in the command history, and so on.
|
||||||
- `ctrl+n`: Clears the command input
|
- `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.
|
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.
|
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
|
### 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.
|
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.
|
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`).
|
||||||
|
|||||||
5
install
@@ -1,8 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
rm -rf /usr/local/bin/ming_bmps
|
rm -rf /usr/local/bin/ming_bmps
|
||||||
cp -r ./bmps /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
|
rm -rf /usr/local/bin/ming_docs
|
||||||
cp -r ./docs /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/ming /usr/local/bin/ming
|
||||||
cp ./target/release/mingUtils_Terminal /usr/local/bin/mingUtils_Terminal
|
cp ./target/release/mingUtils_Terminal /usr/local/bin/mingUtils_Terminal
|
||||||
cp ./target/release/mingGames_Reversi /usr/local/bin/mingGames_Reversi
|
cp ./target/release/mingGames_Reversi /usr/local/bin/mingGames_Reversi
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
rm -rf ~/.local/bin/ming_bmps
|
rm -rf ~/.local/bin/ming_bmps
|
||||||
cp -r ./bmps ~/.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
|
rm -rf ~/.local/bin/ming_docs
|
||||||
cp -r ./docs ~/.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/ming ~/.local/bin/ming
|
||||||
cp ./target/release/mingUtils_Terminal ~/.local/bin/mingUtils_Terminal
|
cp ./target/release/mingUtils_Terminal ~/.local/bin/mingUtils_Terminal
|
||||||
cp ./target/release/mingGames_Reversi ~/.local/bin/mingGames_Reversi
|
cp ./target/release/mingGames_Reversi ~/.local/bin/mingGames_Reversi
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ming-wm-lib"
|
name = "ming-wm-lib"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
repository = "https://github.com/stjet/ming-wm"
|
repository = "https://github.com/stjet/ming-wm"
|
||||||
description = "library for building windows for ming-wm in rust"
|
description = "library for building windows for ming-wm in rust"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::fs::read_dir;
|
||||||
|
|
||||||
use crate::framebuffer_types::{ Dimensions, Point };
|
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<PathBuf, ()> {
|
pub fn concat_paths(current_path: &str, add_path: &str) -> Result<PathBuf, ()> {
|
||||||
let mut new_path = PathBuf::from(current_path);
|
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("/") {
|
if add_path.starts_with("/") {
|
||||||
//absolute path
|
//absolute path
|
||||||
new_path = PathBuf::from(add_path);
|
new_path = PathBuf::from(add_path);
|
||||||
@@ -156,3 +161,36 @@ pub fn get_rest_of_split(split: &mut dyn Iterator<Item = &str>, sep: Option<&str
|
|||||||
rest
|
rest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn path_autocomplete(current_path: &str, partial_path: &str) -> Option<String> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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::messages::{ WindowMessage, WindowMessageResponse };
|
||||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||||
use ming_wm_lib::themes::ThemeInfo;
|
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::dirs::home;
|
||||||
use ming_wm_lib::ipc::listen;
|
use ming_wm_lib::ipc::listen;
|
||||||
use ming_wm::fs::get_all_files;
|
use ming_wm::fs::get_all_files;
|
||||||
@@ -98,6 +98,18 @@ impl WindowLike for AudioPlayer {
|
|||||||
if self.command.len() > 0 {
|
if self.command.len() > 0 {
|
||||||
self.command = self.command.remove_last();
|
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 {
|
} else {
|
||||||
self.command += &key_press.key.to_string();
|
self.command += &key_press.key.to_string();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||||
use ming_wm_lib::utils::{ calc_actual_lines, calc_new_cursor_pos, Substring };
|
use ming_wm_lib::utils::{ calc_actual_lines, calc_new_cursor_pos, Substring };
|
||||||
use ming_wm_lib::dirs::home;
|
use ming_wm_lib::dirs::home;
|
||||||
|
use ming_wm_lib::utils::path_autocomplete;
|
||||||
use ming_wm_lib::ipc::listen;
|
use ming_wm_lib::ipc::listen;
|
||||||
|
|
||||||
const MONO_WIDTH: u8 = 10;
|
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();
|
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);
|
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||||
} else if key_press.key == 'w' {
|
} else if key_press.key == 'w' {
|
||||||
//todo: currently doesn't work on a single space?
|
|
||||||
let line = ¤t_file.content[current_file.line_pos];
|
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
|
//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);
|
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();
|
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);
|
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' {
|
} 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;
|
changed = false;
|
||||||
} else if key_press.key == 'j' || key_press.key == 'k' {
|
} else if key_press.key == 'j' || key_press.key == 'k' {
|
||||||
if key_press.key == 'j' {
|
if key_press.key == 'j' {
|
||||||
current_file.line_pos += 1;
|
current_file.line_pos += self.maybe_num.unwrap_or(1);
|
||||||
if current_file.line_pos == current_file.content.len() {
|
if current_file.line_pos >= current_file.content.len() {
|
||||||
current_file.line_pos = current_file.content.len() - 1;
|
current_file.line_pos = current_file.content.len() - 1;
|
||||||
}
|
}
|
||||||
} else {
|
} 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();
|
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);
|
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||||
changed = false;
|
changed = false;
|
||||||
} else if key_press.key == 'l' {
|
} else if key_press.key == 'l' {
|
||||||
if current_length > 0 {
|
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();
|
let line_len = current_file.content[current_file.line_pos].chars().count();
|
||||||
if current_file.cursor_pos > line_len {
|
if current_file.cursor_pos > line_len {
|
||||||
current_file.cursor_pos = line_len;
|
current_file.cursor_pos = line_len;
|
||||||
@@ -295,10 +302,10 @@ impl WindowLike for Malvim {
|
|||||||
} else {
|
} else {
|
||||||
changed = false;
|
changed = false;
|
||||||
}
|
}
|
||||||
|
//reset maybe_num if not num
|
||||||
if !numbered && self.state != State::Maybeg {
|
if !numbered && self.state != State::Maybeg {
|
||||||
self.maybe_num = None;
|
self.maybe_num = None;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
} else if self.mode == Mode::Command {
|
} else if self.mode == Mode::Command {
|
||||||
self.bottom_message = None;
|
self.bottom_message = None;
|
||||||
let command = self.command.clone().unwrap_or("".to_string());
|
let command = self.command.clone().unwrap_or("".to_string());
|
||||||
@@ -306,6 +313,23 @@ impl WindowLike for Malvim {
|
|||||||
new = self.process_command();
|
new = self.process_command();
|
||||||
self.command = None;
|
self.command = None;
|
||||||
self.mode = Mode::Normal;
|
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
|
} else if key_press.key == '𐘁' { //backspace
|
||||||
if command.len() > 0 {
|
if command.len() > 0 {
|
||||||
self.command = Some(command[..command.len() - 1].to_string());
|
self.command = Some(command[..command.len() - 1].to_string());
|
||||||
@@ -388,7 +412,7 @@ impl WindowLike for Malvim {
|
|||||||
theme_info.alt_secondary
|
theme_info.alt_secondary
|
||||||
};
|
};
|
||||||
instructions.extend(vec![
|
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)),
|
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;
|
used_width = future_used_width;
|
||||||
@@ -550,12 +574,12 @@ impl Malvim {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//t(abe)
|
//t(abe)
|
||||||
self.current_file_index += 1;
|
|
||||||
if self.current_file_index == self.files.len() - 1 {
|
if self.current_file_index == self.files.len() - 1 {
|
||||||
self.files.push(file_info);
|
self.files.push(file_info);
|
||||||
} else {
|
} 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;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -577,15 +601,18 @@ impl Malvim {
|
|||||||
current_file.cursor_pos = 0;
|
current_file.cursor_pos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if first == "w" || first == "write" {
|
} else if first == "x" || first == "w" || first == "write" || first == "q" || first == "quit" {
|
||||||
let current_file = &self.files[self.current_file_index];
|
if first == "x" || first == "w" || first == "write" {
|
||||||
let _ = write(¤t_file.path, ¤t_file.content.join("\n"));
|
let current_file = &self.files[self.current_file_index];
|
||||||
self.files[self.current_file_index].changed = false;
|
let _ = write(¤t_file.path, ¤t_file.content.join("\n"));
|
||||||
self.bottom_message = Some("Written".to_string());
|
self.files[self.current_file_index].changed = false;
|
||||||
} else if first == "q" || first == "quit" {
|
self.bottom_message = Some("Written".to_string());
|
||||||
self.files.remove(self.current_file_index);
|
}
|
||||||
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(0);
|
if first == "x" || first == "q" || first == "quit" {
|
||||||
return true;
|
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" {
|
} else if first == "p" || first == "tabp" {
|
||||||
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(self.files.len() - 1);
|
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(self.files.len() - 1);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use std::io::{ Read, Write };
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs::read_dir;
|
|
||||||
|
|
||||||
use pty_process::blocking;
|
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::messages::{ WindowMessage, WindowMessageResponse, ShortcutType };
|
||||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||||
use ming_wm_lib::themes::ThemeInfo;
|
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::dirs::home;
|
||||||
use ming_wm_lib::ipc::listen;
|
use ming_wm_lib::ipc::listen;
|
||||||
|
|
||||||
//todo: support copy and paste
|
|
||||||
|
|
||||||
const MONO_WIDTH: u8 = 10;
|
const MONO_WIDTH: u8 = 10;
|
||||||
const LINE_HEIGHT: usize = 15;
|
const LINE_HEIGHT: usize = 15;
|
||||||
const PADDING: usize = 4;
|
const PADDING: usize = 4;
|
||||||
@@ -83,7 +80,8 @@ pub struct Terminal {
|
|||||||
process_current_line: Vec<u8>, //bytes of line
|
process_current_line: Vec<u8>, //bytes of line
|
||||||
pty_outerr_rx: Option<Receiver<u8>>,
|
pty_outerr_rx: Option<Receiver<u8>>,
|
||||||
pty_in_tx: Option<Sender<String>>,
|
pty_in_tx: Option<Sender<String>>,
|
||||||
last_command: Option<String>,
|
history: Vec<String>,
|
||||||
|
history_index: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
//for some reason key presses, then moving the window leaves the old window still there, behind it. weird
|
//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
|
} else if key_press.key == '𐘂' { //the enter key
|
||||||
self.lines.push("$ ".to_string() + &self.current_input);
|
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.mode = self.process_command();
|
||||||
self.current_input = String::new();
|
self.current_input = String::new();
|
||||||
} else if key_press.key == '\t' { //tab
|
} else if key_press.key == '\t' { //tab
|
||||||
//autocomplete assuming it's a file system path
|
//autocomplete assuming it's a file system path
|
||||||
//...mostly working
|
//...mostly working
|
||||||
let mut useless_tab = true;
|
|
||||||
if self.current_input.len() > 0 {
|
if self.current_input.len() > 0 {
|
||||||
let partial_path = self.current_input.split(" ").last().unwrap();
|
let partial_path = self.current_input.split(" ").last().unwrap();
|
||||||
if let Ok(new_path) = concat_paths(&self.current_path, partial_path) {
|
if let Some(add) = path_autocomplete(&self.current_path, partial_path) {
|
||||||
let partial_name;
|
self.current_input += &add;
|
||||||
let parent;
|
} else {
|
||||||
if self.current_input.ends_with("/") {
|
return WindowMessageResponse::DoNothing;
|
||||||
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 useless_tab {
|
|
||||||
return WindowMessageResponse::DoNothing;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self.current_input += &key_press.key.to_string();
|
self.current_input += &key_press.key.to_string();
|
||||||
}
|
}
|
||||||
@@ -229,12 +209,25 @@ impl WindowLike for Terminal {
|
|||||||
WindowMessageResponse::JustRedraw
|
WindowMessageResponse::JustRedraw
|
||||||
} else if self.mode == Mode::Input && (key_press.key == 'p' || key_press.key == 'n') {
|
} 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
|
//only the last command is saved unlike other terminals. good enough for me
|
||||||
if key_press.key == 'p' && self.last_command.is_some() {
|
if key_press.key == 'p' && self.history.len() > 0 {
|
||||||
self.current_input = self.last_command.clone().unwrap();
|
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();
|
self.calc_actual_lines();
|
||||||
WindowMessageResponse::JustRedraw
|
WindowMessageResponse::JustRedraw
|
||||||
} else if key_press.key == 'n' {
|
} 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();
|
self.calc_actual_lines();
|
||||||
WindowMessageResponse::JustRedraw
|
WindowMessageResponse::JustRedraw
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -23,7 +23,12 @@ impl WindowLike for Help {
|
|||||||
match message {
|
match message {
|
||||||
WindowMessage::Init(dimensions) => {
|
WindowMessage::Init(dimensions) => {
|
||||||
self.dimensions = 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
|
WindowMessageResponse::JustRedraw
|
||||||
},
|
},
|
||||||
WindowMessage::KeyPress(key_press) => {
|
WindowMessage::KeyPress(key_press) => {
|
||||||
@@ -97,4 +102,3 @@ impl Help {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ pub fn get_font_char_from_fonts(fonts: &[String], c: char) -> (char, Vec<Vec<u8>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let p = dirs::exe_dir(Some(&("ming_bmps/".to_string() + &fonts[0]))).to_string_lossy().to_string();
|
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
|
//so a ? char should be in every font. otherwise will just return blank
|
||||||
get_font_char(&p, '?').unwrap()
|
get_font_char(&p, '?').unwrap_or(('?', vec![vec![0]], 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_files(dir: PathBuf) -> Vec<PathBuf> {
|
pub fn get_all_files(dir: PathBuf) -> Vec<PathBuf> {
|
||||||
|
|||||||