Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows version #631

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ directories = "4"
indicatif = "0.17.1"
serde = { version = "1.0.145", features = ["derive"] }
serde_json = "1.0.86"
tui = { version = "0.19", default-features = false, features = ["termion"] }
termion = "1.5"
unicode-width = "0.1"
itertools = "0.10.5"
tokio = { version = "1", features = ["full"] }
Expand All @@ -73,6 +71,10 @@ whoami = "1.1.2"
rpassword = "7.0"
semver = "1.0.14"

[target.'cfg(any(target_os = "macos", target_family = "unix"))'.dependencies]
tui = { version = "0.19", default-features = false, features = ["termion"] }
termion = "1.5"

[dependencies.tracing-subscriber]
version = "0.3"
default-features = false
Expand Down
3 changes: 3 additions & 0 deletions atuin-common/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ pub fn uuid_v4() -> String {
// I don't want to use ProjectDirs, it puts config in awkward places on
// mac. Data too. Seems to be more intended for GUI apps.
pub fn home_dir() -> PathBuf {
#[cfg(any(target_os = "macos", target_family = "unix"))]
let home = std::env::var("HOME").expect("$HOME not found");
#[cfg(windows)]
let home = std::env::var("LOCALAPPDATA").expect("$LOCALAPPDATA not found");
PathBuf::from(home)
}

Expand Down
50 changes: 29 additions & 21 deletions src/command/client/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ use atuin_client::{

use super::history::ListMode;

#[cfg(any(target_os = "macos", target_family = "unix"))]
mod cursor;
mod duration;
#[cfg(any(target_os = "macos", target_family = "unix"))]
mod event;
#[cfg(any(target_os = "macos", target_family = "unix"))]
mod history_list;
#[cfg(any(target_os = "macos", target_family = "unix"))]
mod interactive;
pub use duration::format_duration;

Expand Down Expand Up @@ -46,7 +50,8 @@ pub struct Cmd {
limit: Option<i64>,

/// Open interactive search UI
#[arg(long, short)]
#[cfg_attr(any(target_os = "macos", target_family = "unix"), arg(long, short))]
#[cfg(any(target_os = "macos", target_family = "unix"))]
interactive: bool,

/// Use human-readable formatting for time
Expand All @@ -62,29 +67,32 @@ pub struct Cmd {

impl Cmd {
pub async fn run(self, db: &mut impl Database, settings: &Settings) -> Result<()> {
#[cfg(any(target_os = "macos", target_family = "unix"))]
if self.interactive {
let item = interactive::history(&self.query, settings, db).await?;
eprintln!("{}", item);
} else {
let list_mode = ListMode::from_flags(self.human, self.cmd_only);
let entries = run_non_interactive(
settings,
list_mode,
self.cwd,
self.exit,
self.exclude_exit,
self.exclude_cwd,
self.before,
self.after,
self.limit,
&self.query,
db,
)
.await?;
if entries == 0 {
std::process::exit(1)
}
};
return Ok(());
}

let list_mode = ListMode::from_flags(self.human, self.cmd_only);
let entries = run_non_interactive(
settings,
list_mode,
self.cwd,
self.exit,
self.exclude_exit,
self.exclude_cwd,
self.before,
self.after,
self.limit,
&self.query,
db,
)
.await?;
if entries == 0 {
std::process::exit(1)
}

Ok(())
}
}
Expand Down
1 change: 1 addition & 0 deletions src/command/client/search/event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{thread, time::Duration};

use crossbeam_channel::unbounded;
#[cfg(any(target_os = "macos", target_family = "unix"))]
use termion::{event::Event as TermEvent, event::Key, input::TermRead};

pub enum Event<I> {
Expand Down
1 change: 1 addition & 0 deletions src/command/client/search/history_list.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::time::Duration;

use atuin_client::history::History;
#[cfg(any(target_os = "macos", target_family = "unix"))]
use tui::{
buffer::Buffer,
layout::Rect,
Expand Down
2 changes: 2 additions & 0 deletions src/command/client/search/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ use std::io::stdout;

use eyre::Result;
use semver::Version;
#[cfg(any(target_os = "macos", target_family = "unix"))]
use termion::{
event::Event as TermEvent, event::Key, event::MouseButton, event::MouseEvent,
input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen,
};
#[cfg(any(target_os = "macos", target_family = "unix"))]
use tui::{
backend::{Backend, TermionBackend},
layout::{Alignment, Constraint, Direction, Layout},
Expand Down
124 changes: 124 additions & 0 deletions src/shell/atuin.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
$env:ATUIN_SESSION = (atuin uuid)
#set your fzf path here
$script:FZF_LOCATION = "C:\ProgramData\chocolatey\bin\fzf.exe"

#TODO SAVE AND RESTORE : RUST_LOG and FZF_DEFAULT_COMMAND

#Based on starship powershell script
function global:prompt {
$origDollarQuestion = $global:?
$origLastExitCode = $global:LASTEXITCODE

# We start from the premise that the command executed correctly, which covers also the fresh console.
$lastExitCodeForPrompt = 0
if ($lastCmd = Get-History -Count 1) {
# In case we have a False on the Dollar hook, we know there's an error.
if (-not $origDollarQuestion) {
# We retrieve the InvocationInfo from the most recent error using $global:error[0]
$lastCmdletError = try { $global:error[0] | Where-Object { $_ -ne $null } | Select-Object -ExpandProperty InvocationInfo } catch { $null }
# We check if the last command executed matches the line that caused the last error, in which case we know
# it was an internal Powershell command, otherwise, there MUST be an error code.
$lastExitCodeForPrompt = if ($null -ne $lastCmdletError -and $lastCmd.CommandLine -eq $lastCmdletError.Line) { 1 } else { $origLastExitCode }
}
}

if ( (-not [string]::IsNullOrEmpty($lastCmd.CommandLine)) -and ($lastCmd.CommandLine -eq $script:atuincmd)) {
$env:RUST_LOG = 'error'; atuin history end --exit "${lastExitCodeForPrompt}" -- "$script:atuinid"; $env:RUST_LOG = ''
}

# Set the number of extra lines in the prompt for PSReadLine prompt redraw.
# Set-PSReadLineOption -ExtraPromptLineCount ($promptText.Split("`n").Length - 1)

# Propagate the original $LASTEXITCODE from before the prompt function was invoked.
$global:LASTEXITCODE = $origLastExitCode

# Propagate the original $? automatic variable value from before the prompt function was invoked.
#
# $? is a read-only or constant variable so we can't directly override it.
# In order to propagate up its original boolean value we will take an action
# which will produce the desired value.
#
# This has to be the very last thing that happens in the prompt function
# since every PowerShell command sets the $? variable.
if ($global:? -ne $origDollarQuestion) {
if ($origDollarQuestion) {
# Simple command which will execute successfully and set $? = True without any other side affects.
1 + 1
}
else {
# Write-Error will set $? to False.
# ErrorAction Ignore will prevent the error from being added to the $Error collection.
Write-Error '' -ErrorAction 'Ignore'
}
}

}

#https://github.com/kelleyma49/PSFzf/blob/0364b14bbd5013a37348fe6681c4980195515ab2/PSFzf.Functions.ps1#L325
function SearchWithFZF() {
$ATUIN_PREFIX = "atuin search --cmd-only"
$INITIAL_QUERY = ""
$env:FZF_DEFAULT_COMMAND = ''
try {
$sleepCmd = ''
$env:FZF_DEFAULT_COMMAND = "$ATUIN_PREFIX ""$INITIAL_QUERY"""

& $script:FZF_LOCATION --ansi `
--disabled --query `"$INITIAL_QUERY`" `
--bind "change:reload:$sleepCmd $ATUIN_PREFIX {q} || cd . " | `
ForEach-Object { $results += $_ }

if (-not [string]::IsNullOrEmpty($results)) {
return $results
}
return ""
}
catch {
Write-Error "Error occurred: $_"
}
finally {
# todo restore $env:FZF_DEFAULT_COMMAND
}
}

#https://github.com/kelleyma49/PSFzf/blob/73fd091883b26866be8d2c4acdfdbd1b11baf45f/PSFzf.Base.ps1#L125
function InvokePromptHack() {
$previousOutputEncoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [Text.Encoding]::UTF8

try {
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
}
finally {
[Console]::OutputEncoding = $previousOutputEncoding
}
}

#https://github.com/kelleyma49/PSFzf/blob/de453b0ab8ec52255a308ddf559b330defb3b842/PSFzf.Git.ps1#L114
function Update-CmdLine($result) {
InvokePromptHack
if ($result.Length -gt 0) {
$result = $result -join " "
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($result)
}
}

# https://github.com/PowerShell/PowerShell/issues/15271
# Override the PSReadLine Enter key handler in order to inject
# custom logic just before submitting a command.
function onEnter() {
# Get the text of the comamnd being submitted.
try {
$line = $null; [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref] $line, [ref] $null)
$script:atuincmd = $line
$script:atuinid = (atuin history start -- "$line")

}
finally {
# Submit the command.
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
}

Set-PSReadLineKeyHandler Enter -ScriptBlock { onEnter }
Set-PSReadlineKeyHandler -Key Ctrl+r -ScriptBlock { Update-CmdLine $(SearchWithFZF) }