mirror of https://github.com/ashhhleyyy/fsh.git
chore: Initial commit
This commit is contained in:
commit
c532ebcc71
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,265 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsh"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"git2",
|
||||
"users",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.13.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "845e007a28f1fcac035715988a234e8ec5458fd825b20a20c7dec74237ef341f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.12.25+1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f68169ef08d6519b2fe133ecc637408d933c0174b23b80bb2f79828966fbaab"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libssh2-sys",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "users"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "fsh"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
git2 = "0.13"
|
||||
users = "0.11"
|
||||
ansi_term = "0.12"
|
|
@ -0,0 +1,11 @@
|
|||
What do you call a fish with no eyes?
|
||||
|
||||
# fsh
|
||||
|
||||
A `fish` theme based on the following:
|
||||
|
||||
- [queer/p](https://github.com/queer/p)
|
||||
- [oh-my-zsh's half-life theme](https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/half-life.zsh-theme)
|
||||
- [Dracula theme](https://draculatheme.com)
|
||||
|
||||
Requires a font with the required icons, I use [Nerd Fonts](https://www.nerdfonts.com/).
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
echo Compiling with cargo...
|
||||
cargo build --release
|
||||
echo Copying to $HOME/.local/bin
|
||||
cp target/release/fsh $HOME/.local/bin/
|
||||
|
||||
if [ ! -f $HOME/.config/fish/functions/fish_prompt.fish ]; then
|
||||
echo "Creating $HOME/.config/fish/functions/fish_prompt.fish"
|
||||
echo "function fish_prompt
|
||||
set FSH_LAST_STATUS \$status
|
||||
fsh \$LAST_STATUS
|
||||
end" > $HOME/.config/fish/functions/fish_prompt.fish
|
||||
fi
|
|
@ -0,0 +1,174 @@
|
|||
use ansi_term::{Colour as AnsiColour, Style};
|
||||
use git2::{Repository, Status as GitStatus};
|
||||
use std::{fmt::Display, path::PathBuf};
|
||||
|
||||
struct PromptComponent {
|
||||
text: String,
|
||||
style: Style,
|
||||
}
|
||||
|
||||
enum Colour {
|
||||
Red,
|
||||
Green,
|
||||
Blue,
|
||||
Yellow,
|
||||
Pink,
|
||||
Purple,
|
||||
}
|
||||
|
||||
fn from_hex(hex: u32) -> AnsiColour {
|
||||
AnsiColour::RGB(
|
||||
(hex >> 16 & 0xff) as u8,
|
||||
(hex >> 8 & 0xff) as u8,
|
||||
(hex >> 0 & 0xff) as u8,
|
||||
)
|
||||
}
|
||||
|
||||
impl Colour {
|
||||
fn to_ansi(&self) -> AnsiColour {
|
||||
match self {
|
||||
Colour::Red => from_hex(0xff5555),
|
||||
Colour::Green => from_hex(0x50fa7b),
|
||||
Colour::Blue => from_hex(0x8be9fd),
|
||||
Colour::Yellow => from_hex(0xf1fa8c),
|
||||
Colour::Pink => from_hex(0xff79c6),
|
||||
Colour::Purple => from_hex(0xbd93f9),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PromptComponent {
|
||||
fn new(text: &str, style: Style) -> Self {
|
||||
Self {
|
||||
text: text.to_string(),
|
||||
style,
|
||||
}
|
||||
}
|
||||
|
||||
fn bold(text: &str, colour: Colour) -> Self {
|
||||
Self::new(text, colour.to_ansi().bold())
|
||||
}
|
||||
|
||||
fn unstyled(text: &str) -> Self {
|
||||
Self {
|
||||
text: text.to_string(),
|
||||
style: Style::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PromptComponent {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!("{}", self.style.paint(&self.text)))
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let last_status = if let Some(status) = std::env::args().into_iter().skip(1).next() {
|
||||
status.parse().unwrap()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let mut components = Vec::new();
|
||||
|
||||
let user = users::get_current_username().map(|s| s.to_string_lossy().into_owned()).unwrap_or_else(|| "unknown".to_string());
|
||||
components.push(PromptComponent::bold(&user, Colour::Purple));
|
||||
|
||||
let home_dir = std::env::var("HOME").unwrap();
|
||||
let pwd = std::env::current_dir().unwrap();
|
||||
let dir = if pwd.starts_with(&home_dir) {
|
||||
let mut buf = PathBuf::new();
|
||||
buf.push("~");
|
||||
if pwd != std::path::Path::new(&home_dir) {
|
||||
let rel_path = pwd.strip_prefix(&home_dir).unwrap();
|
||||
buf.push(rel_path);
|
||||
}
|
||||
format!("{}", buf.to_string_lossy())
|
||||
} else {
|
||||
format!("{:?}", pwd.to_string_lossy())
|
||||
};
|
||||
|
||||
let repo = Repository::discover(".").ok();
|
||||
|
||||
components.push(PromptComponent::unstyled("in"));
|
||||
components.push(PromptComponent::bold(&dir, Colour::Green));
|
||||
|
||||
get_git_info(&mut components, &repo);
|
||||
|
||||
if last_status == 0 {
|
||||
components.push(PromptComponent::bold("\u{f061}", Colour::Yellow));
|
||||
} else {
|
||||
components.push(PromptComponent::bold(&format!("{} \u{f061}", last_status), Colour::Red));
|
||||
}
|
||||
|
||||
for component in components {
|
||||
print!("{} ", component);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_git_info(components: &mut Vec<PromptComponent>, repo: &Option<Repository>) {
|
||||
match repo {
|
||||
Some(repo) => {
|
||||
let head = match repo.head() {
|
||||
Ok(head) => Some(head.shorthand().unwrap().to_string()),
|
||||
Err(ref e) if e.code() == git2::ErrorCode::NotFound => {
|
||||
None
|
||||
}
|
||||
Err(ref e) if e.code() == git2::ErrorCode::UnbornBranch => {
|
||||
// https://github.com/starship/starship/commit/489838e6a24ea1c08be6abe56d066724a1d59abd#diff-d6346fd7d17270b1282142aeeda9c4bc2b7d8fd0f37b24a1c871a9257f0ed0aaR324-R336
|
||||
let mut head_path = repo.path().to_path_buf();
|
||||
head_path.push("HEAD");
|
||||
|
||||
std::fs::read_to_string(&head_path)
|
||||
.ok().unwrap()
|
||||
.lines()
|
||||
.next().unwrap()
|
||||
.trim()
|
||||
.split('/')
|
||||
.last()
|
||||
.map(|r| r.to_owned())
|
||||
}
|
||||
Err(e) => Err(e).unwrap(),
|
||||
};
|
||||
|
||||
let head = head.unwrap_or("(no HEAD)".to_string());
|
||||
|
||||
components.push(PromptComponent::bold(&format!("\u{e725} {}", head), Colour::Blue));
|
||||
|
||||
let mut unstaged = false;
|
||||
let mut staged = false;
|
||||
for status in repo.statuses(None).unwrap().iter() {
|
||||
let status = status.status();
|
||||
if status.intersects(GitStatus::WT_DELETED | GitStatus::WT_MODIFIED | GitStatus::WT_NEW | GitStatus::WT_RENAMED | GitStatus::WT_TYPECHANGE) {
|
||||
unstaged = true;
|
||||
}
|
||||
if status.intersects(GitStatus::INDEX_DELETED | GitStatus::INDEX_MODIFIED | GitStatus::INDEX_NEW | GitStatus::INDEX_RENAMED | GitStatus::INDEX_TYPECHANGE) {
|
||||
staged = true;
|
||||
}
|
||||
}
|
||||
|
||||
let action = match repo.state() {
|
||||
git2::RepositoryState::Merge => Some(PromptComponent::bold("merge", Colour::Pink)),
|
||||
git2::RepositoryState::Revert | git2::RepositoryState::RevertSequence => Some(PromptComponent::bold("revert", Colour::Pink)),
|
||||
git2::RepositoryState::CherryPick | git2::RepositoryState::CherryPickSequence => Some(PromptComponent::bold("cherry pick", Colour::Pink)),
|
||||
git2::RepositoryState::Rebase | git2::RepositoryState::RebaseInteractive | git2::RepositoryState::RebaseMerge => Some(PromptComponent::bold("rebase", Colour::Pink)),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(action) = action {
|
||||
components.push(PromptComponent::unstyled("performing a"));
|
||||
components.push(action);
|
||||
}
|
||||
|
||||
if staged {
|
||||
components.push(PromptComponent::bold("+", Colour::Green));
|
||||
}
|
||||
|
||||
if unstaged {
|
||||
components.push(PromptComponent::bold("●", Colour::Red));
|
||||
}
|
||||
},
|
||||
None => { },
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue