From a64d1acf5c7827913d05d162e3bb61652d30adb9 Mon Sep 17 00:00:00 2001
From: Derek Stavis <dekestavis@gmail.com>
Date: Tue, 23 Feb 2016 22:59:10 -0300
Subject: [PATCH] Implement safe shell reloading inside omf plugin

This commit adds an improved reload code for Oh My Fish, besides
saving the history now the reloading technique keeps directory
history and stack and clears fish_greeting, for a transparent
transition.

The reloading code is now safe regarding to background jobs. exec
wipes fish job control, so the user-facing code under the (just-
introduced by this commit) `omf reload`, and usages under
`omf remove` and `omf update` are now kept safe by a warning.

Recap of the commit:
- Add improved reload code (omf.reload)
- Add a safe reload code (omf.cli.reload)
- Add `omf reload` command
---
 pkg/omf/functions/cli/omf.cli.reload.fish | 18 ++++++++++++++++++
 pkg/omf/functions/cli/omf.cli.remove.fish |  1 +
 pkg/omf/functions/cli/omf.cli.update.fish |  2 ++
 pkg/omf/functions/core/omf.reload.fish    | 11 +++++++++++
 pkg/omf/functions/omf.fish                |  3 +++
 5 files changed, 35 insertions(+)
 create mode 100644 pkg/omf/functions/cli/omf.cli.reload.fish
 create mode 100644 pkg/omf/functions/core/omf.reload.fish

diff --git a/pkg/omf/functions/cli/omf.cli.reload.fish b/pkg/omf/functions/cli/omf.cli.reload.fish
new file mode 100644
index 0000000..4746220
--- /dev/null
+++ b/pkg/omf/functions/cli/omf.cli.reload.fish
@@ -0,0 +1,18 @@
+function omf.cli.reload
+  if not contains -- --force $argv
+    if count (jobs) >/dev/null ^&1
+      __omf.cli.reload.job_warning
+      return 1
+    end
+  end
+  omf.reload
+end
+
+function __omf.cli.reload.job_warning
+  echo (set_color -u)"Reload aborted. There are background jobs:"(set_color normal)
+  echo
+  jobs
+  echo
+  echo "For your safety, finish all background jobs before reloading Oh My Fish."
+  echo "If you are absolutely sure of what you are doing, you can bypass this check using --force."
+end
diff --git a/pkg/omf/functions/cli/omf.cli.remove.fish b/pkg/omf/functions/cli/omf.cli.remove.fish
index 56c12d7..dbbec72 100644
--- a/pkg/omf/functions/cli/omf.cli.remove.fish
+++ b/pkg/omf/functions/cli/omf.cli.remove.fish
@@ -7,6 +7,7 @@ function omf.cli.remove -a name
     switch $code
     case 0
       echo (omf::em)"$name successfully removed."(omf::off)
+      omf.cli.reload
     case 1
       echo (omf::err)"$name could not be removed."(omf::off) 1^&2
     case 2
diff --git a/pkg/omf/functions/cli/omf.cli.update.fish b/pkg/omf/functions/cli/omf.cli.update.fish
index b54b654..6dd2909 100644
--- a/pkg/omf/functions/cli/omf.cli.update.fish
+++ b/pkg/omf/functions/cli/omf.cli.update.fish
@@ -9,4 +9,6 @@ function omf.cli.update
   for package in (omf.packages.list --installed)
     omf.packages.update $package
   end
+
+  omf.cli.reload
 end
diff --git a/pkg/omf/functions/core/omf.reload.fish b/pkg/omf/functions/core/omf.reload.fish
new file mode 100644
index 0000000..55a0e58
--- /dev/null
+++ b/pkg/omf/functions/core/omf.reload.fish
@@ -0,0 +1,11 @@
+function omf.reload -d "Reload fish process via exec(1), keeping some context"
+  set -q CI; and return 0
+
+  history --save
+  set -gx dirprev $dirprev
+  set -gx dirnext $dirnext
+  set -gx dirstack $dirstack
+  set -gx fish_greeting ''
+
+  exec fish
+end
diff --git a/pkg/omf/functions/omf.fish b/pkg/omf/functions/omf.fish
index dab97cb..9acde50 100644
--- a/pkg/omf/functions/omf.fish
+++ b/pkg/omf/functions/omf.fish
@@ -40,6 +40,9 @@ function omf -d "Oh My Fish"
     case "doctor"
       omf.cli.doctor
 
+    case "reload"
+      omf.cli.reload $arguments
+
     case "i" "install" "get"
       omf.cli.install $arguments
 
-- 
GitLab