Repository: gokcehan/lf (go)

Issue:
Log files remain in /tmp if closed by window manager.
If I close that instance of lf by pressing the shortcut bind within lf, it closes with no abnormal effects...

but if I close that with my window manager's typical shortcut for closing programs `super + q` as it happens, lf's log file remains in `/tmp` forever (well until `/tmp` cleanup).

You say in #65 that leftovers will remain in `/tmp` for instances closed by errors, but here it seems that any external closing does the same.

Not sure if this is a decided choice or what, but seems abnormal among programs.

I'm using dwm, if that's relevant.

Pull request description:
Properly handle SIGHUP and SIGTERM
Properly handle exit signals SIGHUP and SIGTERM to avoid exiting prematurely.

Fixes #300, #292 

To preserve system independence, according to the [documentation](https://golang.org/pkg/os/signal/), when Windows sends CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT, Notify will return SIGTERM like a *nix system.

Patch:
diff --git a/.travis.yml b/.travis.yml
index 93b0b25..6639f76 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
 language: go
 install:
-  - go get github.com/nsf/termbox-go
+  - go get github.com/doronbehar/termbox-go
   - go get gopkg.in/djherbis/times.v1
 before_deploy:
   - gen/xbuild.sh
diff --git a/app.go b/app.go
index 7f79796..06fb18d 100644
--- a/app.go
+++ b/app.go
@@ -7,6 +7,8 @@ import (
 	"log"
 	"os"
 	"os/exec"
+	"os/signal"
+	"syscall"
 	"path/filepath"
 	"strings"
 	"time"
@@ -34,11 +36,24 @@ func newApp() *app {
 	ui := newUI()
 	nav := newNav(ui.wins[0].h)
 
+	quitChan := make(chan bool, 1)
+
+	osChan := make(chan os.Signal, 1)
+	signal.Notify(osChan, os.Interrupt, syscall.SIGHUP, syscall.SIGTERM)
+	go func() {
+		<-osChan
+		nav.copyTotalChan <- -nav.copyTotal
+		nav.moveTotalChan <- -nav.moveTotal
+		nav.deleteTotalChan <- -nav.deleteTotal
+		quitChan <- true
+		return
+	}()
+
 	return &app{
 		ui:       ui,
 		nav:      nav,
 		ticker:   new(time.Ticker),
-		quitChan: make(chan bool, 1),
+		quitChan: quitChan,
 	}
 }
 
diff --git a/client.go b/client.go
index 6d19ba7..1c580bb 100644
--- a/client.go
+++ b/client.go
@@ -10,7 +10,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/nsf/termbox-go"
+	"github.com/doronbehar/termbox-go"
 )
 
 func run() {
diff --git a/colors.go b/colors.go
index a976831..9d3ac83 100644
--- a/colors.go
+++ b/colors.go
@@ -7,7 +7,7 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/nsf/termbox-go"
+	"github.com/doronbehar/termbox-go"
 )
 
 const gAnsiColorResetMask = termbox.AttrBold | termbox.AttrUnderline | termbox.AttrReverse
diff --git a/doc.go b/doc.go
index 350f4dd..e34292e 100644
--- a/doc.go
+++ b/doc.go
@@ -693,6 +693,39 @@ pipe with a SIGPIPE when enough lines are read. When everything else fails, you
 can make use of the height argument to only feed the first portion of the file
 to a program for preview.
 
+Changing Directory
+
+lf changes the working directory of the process to the current directory so
+that shell commands always work in the displayed directory. After quitting, it
+returns to the original directory where it is first launched like all shell
+programs. If you want to stay in the current directory after quitting, you can
+use one of the example wrapper shell scripts provided in the repository.
+
+There is a special command 'on-cd' that runs a shell command when it is defined
+and the directory is changed. You can define it just as you would define any
+other command:
+
+    cmd on-cd &{{
+        # display git repository status in your prompt
+        source /usr/share/git/completion/git-prompt.sh
+        GIT_PS1_SHOWDIRTYSTATE=auto
+        GIT_PS1_SHOWSTASHSTATE=auto
+        GIT_PS1_SHOWUNTRACKEDFILES=auto
+        GIT_PS1_SHOWUPSTREAM=auto
+        git=$(__git_ps1 " (%s)") || true
+        fmt="\033[32;1m%u@%h\033[0m:\033[34;1m%w/\033[0m\033[1m%f$git\033[0m"
+        lf -remote "send $id set promptfmt \"$fmt\""
+    }}
+
+This command runs whenever you change directory but not on startup. You can add
+an extra call to make it run on startup as well:
+
+    cmd on-cd &{{ # ... }}
+    on-cd
+
+Note that all shell commands are possible but `%` and `&` are usually more
+appropriate as `$` and `!` causes flickers and pauses respectively.
+
 Colorschemes
 
 lf tries to automatically adapt its colors to the environment. On startup,
diff --git a/docstring.go b/docstring.go
index f9d5111..7afa386 100644
--- a/docstring.go
+++ b/docstring.go
@@ -724,6 +724,41 @@ everything else fails, you can make use of the height argument to only feed
 the first portion of the file to a program for preview.
 
 
+Changing Directory
+
+lf changes the working directory of the process to the current directory so
+that shell commands always work in the displayed directory. After quitting,
+it returns to the original directory where it is first launched like all
+shell programs. If you want to stay in the current directory after quitting,
+you can use one of the example wrapper shell scripts provided in the
+repository.
+
+There is a special command 'on-cd' that runs a shell command when it is
+defined and the directory is changed. You can define it just as you would
+define any other command:
+
+    cmd on-cd &{{
+        # display git repository status in your prompt
+        source /usr/share/git/completion/git-prompt.sh
+        GIT_PS1_SHOWDIRTYSTATE=auto
+        GIT_PS1_SHOWSTASHSTATE=auto
+        GIT_PS1_SHOWUNTRACKEDFILES=auto
+        GIT_PS1_SHOWUPSTREAM=auto
+        git=$(__git_ps1 " (%s)") || true
+        fmt="\033[32;1m%u@%h\033[0m:\033[34;1m%w/\033[0m\033[1m%f$git\033[0m"
+        lf -remote "send $id set promptfmt \"$fmt\""
+    }}
+
+This command runs whenever you change directory but not on startup. You can
+add an extra call to make it run on startup as well:
+
+    cmd on-cd &{{ # ... }}
+    on-cd
+
+Note that all shell commands are possible but '%' and '&' are usually more
+appropriate as '$' and '!' causes flickers and pauses respectively.
+
+
 Colorschemes
 
 lf tries to automatically adapt its colors to the environment. On startup,
diff --git a/eval.go b/eval.go
index 2e78c52..0ef9604 100644
--- a/eval.go
+++ b/eval.go
@@ -330,6 +330,12 @@ func (e *cmdExpr) eval(app *app, args []string) {
 	app.ui.loadFileInfo(app.nav)
 }
 
+func onChdir(app *app) {
+	if cmd, ok := gOpts.cmds["on-cd"]; ok {
+		cmd.eval(app, nil)
+	}
+}
+
 func splitKeys(s string) (keys []string) {
 	for i := 0; i < len(s); {
 		r, w := utf8.DecodeRuneInString(s[i:])
@@ -535,6 +541,7 @@ func insert(app *app, arg string) {
 
 		if wd != path {
 			app.nav.marks["'"] = wd
+			onChdir(app)
 		}
 	case app.ui.cmdPrefix == "mark-remove: ":
 		normal(app)
@@ -610,6 +617,7 @@ func (e *callExpr) eval(app *app, args []string) {
 		}
 		app.ui.loadFile(app.nav)
 		app.ui.loadFileInfo(app.nav)
+		onChdir(app)
 	case "open":
 		if app.ui.cmdPrefix != "" && app.ui.cmdPrefix != ">" {
 			normal(app)
@@ -628,6 +636,7 @@ func (e *callExpr) eval(app *app, args []string) {
 			}
 			app.ui.loadFile(app.nav)
 			app.ui.loadFileInfo(app.nav)
+			onChdir(app)
 			return
 		}
 
@@ -903,6 +912,7 @@ func (e *callExpr) eval(app *app, args []string) {
 
 		if wd != path {
 			app.nav.marks["'"] = wd
+			onChdir(app)
 		}
 	case "select":
 		if len(e.args) != 1 {
@@ -932,6 +942,7 @@ func (e *callExpr) eval(app *app, args []string) {
 
 		if wd != path {
 			app.nav.marks["'"] = wd
+			onChdir(app)
 		}
 	case "glob-select":
 		if len(e.args) != 1 {
diff --git a/go.mod b/go.mod
index 7b68baf..3508d63 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/gokcehan/lf
 go 1.12
 
 require (
+	github.com/doronbehar/termbox-go v0.0.0-20191006141301-8c9470559e05
 	github.com/mattn/go-runewidth v0.0.4
-	github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e
 	gopkg.in/djherbis/times.v1 v1.2.0
 )
diff --git a/go.sum b/go.sum
index e8f606b..c7cbdf9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,10 @@
+github.com/doronbehar/termbox-go v0.0.0-20190817171036-93860e161317 h1:mdOm+1RdYwVwC4Wjb53M5L96fRwWJ8gI7YXwwiCsHTk=
+github.com/doronbehar/termbox-go v0.0.0-20190817171036-93860e161317/go.mod h1:cHYbFQiZNC8LPG6clYoLMKAl0xx7KR75RPsHtG/f1Hk=
+github.com/doronbehar/termbox-go v0.0.0-20191006140624-aa2cdd26fb8c h1:qvLYQAhDCaMq+XiQ+t4YLaTJtUyHC1r20odd6ryKYIk=
+github.com/doronbehar/termbox-go v0.0.0-20191006140624-aa2cdd26fb8c/go.mod h1:cHYbFQiZNC8LPG6clYoLMKAl0xx7KR75RPsHtG/f1Hk=
+github.com/doronbehar/termbox-go v0.0.0-20191006141301-8c9470559e05 h1:pmXx7j8+mmkFJB2+qoB1C/Mz8SWvMlHTxSWOptJrr7E=
+github.com/doronbehar/termbox-go v0.0.0-20191006141301-8c9470559e05/go.mod h1:cHYbFQiZNC8LPG6clYoLMKAl0xx7KR75RPsHtG/f1Hk=
 github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
 github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e h1:Vbib8wJAaMEF9jusI/kMSYMr/LtRzM7+F9MJgt/nH8k=
-github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
 gopkg.in/djherbis/times.v1 v1.2.0 h1:UCvDKl1L/fmBygl2Y7hubXCnY7t4Yj46ZrBFNUipFbM=
 gopkg.in/djherbis/times.v1 v1.2.0/go.mod h1:AQlg6unIsrsCEdQYhTzERy542dz6SFdQFZFv6mUY0P8=
diff --git a/lf.1 b/lf.1
index 1f733aa..359230b 100644
--- a/lf.1
+++ b/lf.1
@@ -638,6 +638,33 @@ Since this script is called for each file selection change it needs to be as eff
 .EE
 .PP
 Another important consideration for efficiency is the use of programs with short startup times for preview. For this reason, 'highlight' is recommended over 'pygmentize' for syntax highlighting. Besides, it is also important that the application is processing the file on the fly rather than first reading it to the memory and then do the processing afterwards. This is especially relevant for big files. lf automatically closes the previewer script output pipe with a SIGPIPE when enough lines are read. When everything else fails, you can make use of the height argument to only feed the first portion of the file to a program for preview.
+.SH CHANGING DIRECTORY
+lf changes the working directory of the process to the current directory so that shell commands always work in the displayed directory. After quitting, it returns to the original directory where it is first launched like all shell programs. If you want to stay in the current directory after quitting, you can use one of the example wrapper shell scripts provided in the repository.
+.PP
+There is a special command 'on-cd' that runs a shell command when it is defined and the directory is changed. You can define it just as you would define any other command:
+.PP
+.EX
+    cmd on-cd &{{
+        # display git repository status in your prompt
+        source /usr/share/git/completion/git-prompt.sh
+        GIT_PS1_SHOWDIRTYSTATE=auto
+        GIT_PS1_SHOWSTASHSTATE=auto
+        GIT_PS1_SHOWUNTRACKEDFILES=auto
+        GIT_PS1_SHOWUPSTREAM=auto
+        git=$(__git_ps1 " (%s)") || true
+        fmt="\e033[32;1m%u@%h\e033[0m:\e033[34;1m%w/\e033[0m\e033[1m%f$git\e033[0m"
+        lf -remote "send $id set promptfmt \e"$fmt\e""
+    }}
+.EE
+.PP
+This command runs whenever you change directory but not on startup. You can add an extra call to make it run on startup as well:
+.PP
+.EX
+    cmd on-cd &{{ # ... }}
+    on-cd
+.EE
+.PP
+Note that all shell commands are possible but `%` and `&` are usually more appropriate as `$` and `!` causes flickers and pauses respectively.
 .SH COLORSCHEMES
 lf tries to automatically adapt its colors to the environment. On startup, first '$LS_COLORS' environment variable is checked. This variable is used by GNU ls to configure its colors based on file types and extensions. The value of this variable is often set by GNU dircolors in a shell configuration file. dircolors program itself can be configured with a configuration file. dircolors supports 256 colors along with common attributes such as bold and underline.
 .PP
diff --git a/ui.go b/ui.go
index 9c38929..722f2ab 100644
--- a/ui.go
+++ b/ui.go
@@ -15,8 +15,8 @@ import (
 	"unicode"
 	"unicode/utf8"
 
+	"github.com/doronbehar/termbox-go"
 	"github.com/mattn/go-runewidth"
-	"github.com/nsf/termbox-go"
 )
 
 const gEscapeCode = 27


Test patch:
diff --git a/colors_test.go b/colors_test.go
index ff93b48..2d4b868 100644
--- a/colors_test.go
+++ b/colors_test.go
@@ -3,7 +3,7 @@ package main
 import (
 	"testing"
 
-	"github.com/nsf/termbox-go"
+	"github.com/doronbehar/termbox-go"
 )
 
 func TestApplyAnsiCodes(t *testing.T) {