fix messing up users terminal after opening file in vi (related to #173)

This commit is contained in:
Stephan Dilly 2020-07-07 12:53:17 +02:00
parent 0fd8a0e7e0
commit 1cd74ad02e
4 changed files with 47 additions and 42 deletions

View file

@ -200,7 +200,11 @@ impl App {
self.external_editor_popup.hide();
if let InputState::Paused = polling_state {
let result = match self.file_to_open.take() {
Some(path) => crate::open_file_in_editor(&path),
Some(path) => {
ExternalEditorComponent::open_file_in_editor(
&path,
)
}
None => self.commit.show_editor(),
};

View file

@ -1,6 +1,7 @@
use super::{
textinput::TextInputComponent, visibility_blocking,
CommandBlocking, CommandInfo, Component, DrawableComponent,
ExternalEditorComponent,
};
use crate::{
get_app_config_path, keys,
@ -13,15 +14,10 @@ use asyncgit::{
sync::{self, CommitId, HookResult},
CWD,
};
use crossterm::{
event::Event,
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
};
use scopeguard::defer;
use crossterm::event::Event;
use std::{
fs::File,
io::{self, Read, Write},
io::{Read, Write},
path::PathBuf,
};
use tui::{backend::Backend, layout::Rect, Frame};
@ -144,11 +140,11 @@ impl CommitComponent {
pub fn show_editor(&mut self) -> Result<()> {
const COMMIT_MSG_FILE_NAME: &str = "COMMITMSG_EDITOR";
//TODO: use a tmpfile here
let mut config_path: PathBuf = get_app_config_path()?;
config_path.push(COMMIT_MSG_FILE_NAME);
{
//TODO: use a tmpfile here
let mut file = File::create(&config_path)?;
file.write_fmt(format_args!(
"{}\n",
@ -157,16 +153,10 @@ impl CommitComponent {
file.write_all(strings::COMMIT_EDITOR_MSG.as_bytes())?;
}
io::stdout().execute(LeaveAlternateScreen)?;
defer! {
io::stdout().execute(EnterAlternateScreen).expect("reset terminal");
}
crate::open_file_in_editor(&config_path)?;
ExternalEditorComponent::open_file_in_editor(&config_path)?;
let mut message = String::new();
//TODO: see above
let mut file = File::open(&config_path)?;
file.read_to_string(&mut message)?;
drop(file);

View file

@ -6,8 +6,14 @@ use crate::{
strings,
ui::{self, style::SharedTheme},
};
use anyhow::Result;
use crossterm::event::Event;
use anyhow::{anyhow, Result};
use crossterm::{
event::Event,
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
};
use scopeguard::defer;
use std::{env, io, path::Path, process::Command};
use tui::{
backend::Backend,
layout::Rect,
@ -29,6 +35,34 @@ impl ExternalEditorComponent {
theme,
}
}
///
pub fn open_file_in_editor(path: &Path) -> Result<()> {
io::stdout().execute(LeaveAlternateScreen)?;
defer! {
io::stdout().execute(EnterAlternateScreen).expect("reset terminal");
}
let mut editor = env::var("GIT_EDITOR")
.ok()
.or_else(|| env::var("VISUAL").ok())
.or_else(|| env::var("EDITOR").ok())
.unwrap_or_else(|| String::from("vi"));
editor.push_str(&format!(" {}", path.to_string_lossy()));
let mut editor = editor.split_whitespace();
let command = editor.next().ok_or_else(|| {
anyhow!("unable to read editor command")
})?;
Command::new(command)
.args(editor)
.status()
.map_err(|e| anyhow!("\"{}\": {}", command, e))?;
Ok(())
}
}
impl DrawableComponent for ExternalEditorComponent {

View file

@ -43,13 +43,12 @@ use scopeguard::defer;
use scopetime::scope_time;
use simplelog::{Config, LevelFilter, WriteLogger};
use spinner::Spinner;
use std::process::Command;
use std::{
env, fs,
fs::File,
io::{self, Write},
panic,
path::{Path, PathBuf},
path::PathBuf,
process,
time::{Duration, Instant},
};
@ -242,28 +241,6 @@ fn migrate_config() -> Result<()> {
Ok(())
}
fn open_file_in_editor(path: &Path) -> Result<()> {
let mut editor = env::var("GIT_EDITOR")
.ok()
.or_else(|| env::var("VISUAL").ok())
.or_else(|| env::var("EDITOR").ok())
.unwrap_or_else(|| String::from("vi"));
editor.push_str(&format!(" {}", path.to_string_lossy()));
let mut editor = editor.split_whitespace();
let command = editor
.next()
.ok_or_else(|| anyhow!("unable to read editor command"))?;
Command::new(command)
.args(editor)
.status()
.map_err(|e| anyhow!("\"{}\": {}", command, e))?;
Ok(())
}
fn get_app_cache_path() -> Result<PathBuf> {
let mut path = dirs::cache_dir()
.ok_or_else(|| anyhow!("failed to find os cache dir."))?;