From 1d4a284ae9d3f7eab282ee1234f958adbe3ec616 Mon Sep 17 00:00:00 2001 From: stjet <49297268+stjet@users.noreply.github.com> Date: Thu, 13 Mar 2025 08:04:03 +0000 Subject: [PATCH] terminal tab path autocomplete, docs, different int size fix? --- docs/system/README.md | 2 +- docs/system/fonts.md | 9 +++++++++ linux/src/fb.rs | 12 ++++++------ src/bin/terminal.rs | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 docs/system/fonts.md diff --git a/docs/system/README.md b/docs/system/README.md index cb614c6..ad3277c 100644 --- a/docs/system/README.md +++ b/docs/system/README.md @@ -92,7 +92,7 @@ As windows are mostly just like other window-likes, they can be compiled in as p As apps are just any old binary that support the IPC that `proxy_window_like.rs` does, they can be written in any language, and be completely separate from this project. Of course, if they are not written in Rust, extra code is needed to do that IPC. -//but what apps can be opened are currently hardcoded in start menu and the window manager +Binaries in the same directory as the window manager binary and following a specific name format are automatically added to the start menu. See `docs/system/writing_windows.md` for more information. Some of the apps included are Malvim, the subset of vim (a text editor) I use, Minesweeper, and an Audio Player. diff --git a/docs/system/fonts.md b/docs/system/fonts.md new file mode 100644 index 0000000..fff8d38 --- /dev/null +++ b/docs/system/fonts.md @@ -0,0 +1,9 @@ +The build script (`build.rs`) takes the font char BMP (must have an alpha channel and transparent background) files in `bmps` and processes them into `.alpha` files which are read by the window manager to draw characters from a specific font. The `.alpha` files are very simple. They include the vertical offset of the character (the second character in the BMP file name), as well as several lines of CSV, where each value is either blank (0) or a value from 0-255 representing the alpha value of that pixel in the original BMP file. + +The default included fonts are `nimbus-roman`, `nimbus-romono` (a version of `nimbus-roman` slightly modified to be better for monospace environments), and `shippori-mincho` for Japanese (and technically Chinese). + +License information for those fonts can be font in the `README.md` at the project root. + +Custom fonts can be added, though to get the window manager and window binaries to use the font, the source needs to be modified and recompiled. + +Fonts must have a `?` char, which will be used when characters that are not defined in the font are encountered. diff --git a/linux/src/fb.rs b/linux/src/fb.rs index c8400d5..35dbac2 100644 --- a/linux/src/fb.rs +++ b/linux/src/fb.rs @@ -2,13 +2,13 @@ use std::fs::{ File, OpenOptions }; use std::os::fd::AsRawFd; use std::ptr; -use libc::{ ioctl, mmap }; +use libc::{ ioctl, mmap, munmap, c_ulong, c_int }; //https://stackoverflow.com/a/75402838 //https://github.com/torvalds/linux/blob/master/include/uapi/linux/fb.h -pub const FBIOGET_VSCREENINFO: u64 = 0x4600; -pub const FBIOGET_FSCREENINFO: u64 = 0x4602; +pub const FBIOGET_VSCREENINFO: c_ulong = 0x4600; +pub const FBIOGET_FSCREENINFO: c_ulong = 0x4602; //https://www.kernel.org/doc/html/latest/fb/api.html @@ -105,7 +105,7 @@ impl Framebuffer { OpenOptions::new().read(true).write(true).open(path).map_err(|_| ()) } - fn get_vscreeninfo(raw_fd: i32) -> Result { + fn get_vscreeninfo(raw_fd: c_int) -> Result { let mut vi: FB_VAR_SCREENINFO = Default::default(); let result = unsafe { ioctl(raw_fd, FBIOGET_VSCREENINFO, &mut vi) @@ -117,7 +117,7 @@ impl Framebuffer { } } - fn get_fscreeninfo(raw_fd: i32) -> Result { + fn get_fscreeninfo(raw_fd: c_int) -> Result { let mut fi: FB_FIX_SCREENINFO = Default::default(); let result = unsafe { ioctl(raw_fd, FBIOGET_FSCREENINFO, &mut fi) @@ -139,7 +139,7 @@ impl Framebuffer { impl Drop for Framebuffer { fn drop(&mut self) { unsafe { - libc::munmap(self.pointer, self.size); + munmap(self.pointer, self.size); } } } diff --git a/src/bin/terminal.rs b/src/bin/terminal.rs index f7eaaa8..e4e5e1f 100644 --- a/src/bin/terminal.rs +++ b/src/bin/terminal.rs @@ -7,6 +7,7 @@ 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; @@ -116,6 +117,36 @@ impl WindowLike for Terminal { self.last_command = Some(self.current_input.clone()); 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 useless_tab { + return WindowMessageResponse::DoNothing; + } } else { self.current_input += &key_press.key.to_string(); } @@ -291,6 +322,8 @@ impl Terminal { if let Ok(new_path) = concat_paths(&self.current_path, arg) { if new_path.is_dir() { self.current_path = new_path.to_str().unwrap().to_string(); + } else { + self.lines.push("Path not found or not directory".to_string()); } } Mode::Input