Repository: dundee/gdu
Pull request #212 (2023-02-16 20:58:46)

chore(deps): bump github/codeql-action from 1 to 2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's changelog</a>.</em></p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/github/codeql-action/commit/17573ee1cc1b9d061760f3a006fc4aac4f944fd5"><code>17573ee</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/github/codeql-action/issues/1534">#1534</a> from github/update-v2.2.4-40babc141</li>
<li><a href="https://github.com/github/codeql-action/commit/b6975b4b1a0223cc1d1b0c6c03b97914e7ed4fa0"><code>b6975b4</code></a> Update changelog for v2.2.4</li>
<li><a href="https://github.com/github/codeql-action/commit/40babc141f77ccfec65b348cf43f3aab0f1638f8"><code>40babc1</code></a> Tools telemetry: accurately report when feature flags were inaccessible  (<a href="https://github-redirect.dependabot.com/github/codeql-action/issues/1532">#1532</a>)</li>
<li><a href="https://github.com/github/codeql-action/commit/7ba5ed7eed12f15064a031cc1fa3341f93764020"><code>7ba5ed7</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/github/codeql-action/issues/1531">#1531</a> from github/mergeback/v2.2.3-to-main-8775e868</li>
<li><a href="https://github.com/github/codeql-action/commit/21f3020df667a6f408b49f157f6becc935e16d6e"><code>21f3020</code></a> Update checked-in dependencies</li>
<li><a href="https://github.com/github/codeql-action/commit/b872c5adfda610d4e1ff5ff7cf301827fe6507fb"><code>b872c5a</code></a> Update changelog and version after v2.2.3</li>
<li><a href="https://github.com/github/codeql-action/commit/8775e868027fa230df8586bdf502bbd9b618a477"><code>8775e86</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/github/codeql-action/issues/1530">#1530</a> from github/update-v2.2.3-c4e22e9fc</li>
<li><a href="https://github.com/github/codeql-action/commit/a2ad80b9661d89ad2b787bcd23f4ad4f6cd1ee27"><code>a2ad80b</code></a> Update changelog for v2.2.3</li>
<li><a href="https://github.com/github/codeql-action/commit/c4e22e9fce3e0aaa41ffc8c3d1e4bed59ac35f4b"><code>c4e22e9</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/github/codeql-action/issues/1529">#1529</a> from github/henrymercer/remove-bypass-toolcache-flags</li>
<li><a href="https://github.com/github/codeql-action/commit/db534af2ae193414153f312fdefafa843f635022"><code>db534af</code></a> Remove feature flags for bypassing the toolcache</li>
<li>Additional commits viewable in <a href="https://github.com/github/codeql-action/compare/v1...v2">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=1&new-version=2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>> **Note**
> Automatic rebases have been disabled on this pull request as it has been open for over 30 days.


codecov[bot]: # [Codecov](https://codecov.io/gh/dundee/gdu/pull/212?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde) Report
Base: **94.07**% // Head: **94.10**% // Increases project coverage by **`+0.03%`** :tada:
> Coverage data is based on head [(`2bbfca7`)](https://codecov.io/gh/dundee/gdu/pull/212?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde) compared to base [(`0a92b13`)](https://codecov.io/gh/dundee/gdu/commit/0a92b133a9d715c614e9d98de4daafecff5a4b00?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde).
> Patch has no changes to coverable lines.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #212      +/-   ##
==========================================
+ Coverage   94.07%   94.10%   +0.03%     
==========================================
  Files          29       29              
  Lines        2733     2733              
==========================================
+ Hits         2571     2572       +1     
+ Misses        124      123       -1     
  Partials       38       38              
```


| [Impacted Files](https://codecov.io/gh/dundee/gdu/pull/212?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde) | Coverage Δ | |
|---|---|---|
| [report/export.go](https://codecov.io/gh/dundee/gdu/pull/212?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde#diff-cmVwb3J0L2V4cG9ydC5nbw==) | `92.50% <0.00%> (+0.62%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/dundee/gdu/pull/212?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Daniel+Milde).


Patch:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index dc6e7f1..91e2cf0 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -39,7 +39,7 @@ jobs:
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@v1
+      uses: github/codeql-action/init@v2
       with:
         languages: ${{ matrix.language }}
         # If you wish to specify custom queries, you can do so here or in a config file.
@@ -50,7 +50,7 @@ jobs:
     # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
     # If this step fails, then you should remove it and run the build manually (see below)
     - name: Autobuild
-      uses: github/codeql-action/autobuild@v1
+      uses: github/codeql-action/autobuild@v2
 
     # ℹ️ Command-line programs to run using the OS shell.
     # 📚 https://git.io/JvXDl
@@ -64,4 +64,4 @@ jobs:
     #   make release
 
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v1
+      uses: github/codeql-action/analyze@v2
diff --git a/Makefile b/Makefile
index 396e681..ccdb6ff 100644
--- a/Makefile
+++ b/Makefile
@@ -99,14 +99,18 @@ gobench:
 	go test -bench=. $(PACKAGE)/pkg/analyze
 
 benchmark:
+	sudo cpupower frequency-set -g performance
 	hyperfine --export-markdown=bench-cold.md \
 		--prepare 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches' \
+		--ignore-failure \
 		'gdu -npc ~' 'gdu -gnpc ~' 'dua ~' 'duc index ~' 'ncdu -0 -o /dev/null ~' \
-		'diskus ~' 'du -hs ~' 'dust -d0 ~'
+		'diskus ~' 'du -hs ~' 'dust -d0 ~' 'pdu ~'
 	hyperfine --export-markdown=bench-warm.md \
 		--warmup 5 \
+		--ignore-failure \
 		'gdu -npc ~' 'gdu -gnpc ~' 'dua ~' 'duc index ~' 'ncdu -0 -o /dev/null ~' \
-		'diskus ~' 'du -hs ~' 'dust -d0 ~'
+		'diskus ~' 'du -hs ~' 'dust -d0 ~' 'pdu ~'
+	sudo cpupower frequency-set -g schedutil
 
 clean:
 	go mod tidy
diff --git a/README.md b/README.md
index f9bf0fe..339bb1c 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ Using curl:
     chmod +x gdu_linux_amd64
     mv gdu_linux_amd64 /usr/bin/gdu
 
-[Arch Linux](https://aur.archlinux.org/packages/gdu/):
+[Arch Linux](https://archlinux.org/packages/community/x86_64/gdu/):
 
     pacman -S gdu
 
@@ -159,7 +159,7 @@ Gdu can read (and write) YAML configuration file.
 * To configure gdu to permanently run in gray-scale color mode:
 
 ```
-echo "no-color: true" > ~/.gdu.yaml
+echo "no-color: true" >> ~/.gdu.yaml
 ```
 
 * To set default sorting in configuration file:
@@ -170,6 +170,12 @@ sorting:
     order: desc
 ```
 
+* To configure gdu to set CWD variable when browsing directories:
+
+```
+echo "change-cwd: true" >> ~/.gdu.yaml
+```
+
 * To save the current configuration
 
 ```
@@ -240,27 +246,29 @@ Filesystem cache was cleared using `sync; echo 3 | sudo tee /proc/sys/vm/drop_ca
 
 | Command | Mean [s] | Min [s] | Max [s] | Relative |
 |:---|---:|---:|---:|---:|
-| `gdu -npc ~` | 5.390 ± 0.094 | 5.303 | 5.644 | 1.00 ± 0.02 |
-| `gdu -gnpc ~` | 6.275 ± 2.406 | 5.379 | 13.097 | 1.17 ± 0.45 |
-| `dua ~` | 6.727 ± 0.019 | 6.689 | 6.748 | 1.25 ± 0.01 |
-| `duc index ~` | 31.377 ± 0.176 | 31.085 | 31.701 | 5.83 ± 0.06 |
-| `ncdu -0 -o /dev/null ~` | 31.311 ± 0.100 | 31.170 | 31.507 | 5.82 ± 0.05 |
-| `diskus ~` | 5.383 ± 0.044 | 5.287 | 5.440 | 1.00 |
-| `du -hs ~` | 30.333 ± 0.408 | 29.865 | 31.086 | 5.63 ± 0.09 |
-| `dust -d0 ~` | 6.889 ± 0.354 | 6.738 | 7.889 | 1.28 ± 0.07 |
+| `gdu -npc ~` | 4.995 ± 0.032 | 4.964 | 5.083 | 1.00 |
+| `gdu -gnpc ~` | 5.080 ± 0.132 | 5.000 | 5.339 | 1.02 ± 0.03 |
+| `diskus ~` | 5.174 ± 0.042 | 5.113 | 5.231 | 1.04 ± 0.01 |
+| `pdu ~` | 5.940 ± 0.011 | 5.918 | 5.956 | 1.19 ± 0.01 |
+| `dua ~` | 6.176 ± 0.012 | 6.160 | 6.195 | 1.24 ± 0.01 |
+| `dust -d0 ~` | 6.556 ± 0.497 | 6.217 | 7.319 | 1.31 ± 0.10 |
+| `du -hs ~` | 24.105 ± 0.061 | 24.045 | 24.220 | 4.83 ± 0.03 |
+| `ncdu -0 -o /dev/null ~` | 25.065 ± 0.071 | 24.970 | 25.180 | 5.02 ± 0.04 |
+| `duc index ~` | 25.711 ± 3.168 | 24.550 | 34.723 | 5.15 ± 0.64 |
 
 ### Warm cache
 
 | Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
 |:---|---:|---:|---:|---:|
-| `gdu -npc ~` | 840.3 ± 13.4 | 817.7 | 867.8 | 1.74 ± 0.06 |
-| `gdu -gnpc ~` | 1038.4 ± 9.7 | 1021.3 | 1054.1 | 2.15 ± 0.07 |
-| `dua ~` | 635.0 ± 20.6 | 602.6 | 669.9 | 1.32 ± 0.06 |
-| `duc index ~` | 1879.5 ± 18.5 | 1853.5 | 1922.1 | 3.90 ± 0.13 |
-| `ncdu -0 -o /dev/null ~` | 2618.5 ± 10.0 | 2607.9 | 2634.8 | 5.43 ± 0.18 |
-| `diskus ~` | 482.4 ± 15.6 | 456.5 | 516.9 | 1.00 |
-| `du -hs ~` | 1508.7 ± 8.2 | 1501.1 | 1524.3 | 3.13 ± 0.10 |
-| `dust -d0 ~` | 832.5 ± 27.0 | 797.3 | 895.5 | 1.73 ± 0.08 |
+| `pdu ~` | 354.9 ± 3.9 | 350.1 | 363.2 | 1.00 |
+| `diskus ~` | 406.5 ± 6.9 | 395.2 | 419.2 | 1.15 ± 0.02 |
+| `dua ~` | 525.0 ± 10.0 | 506.8 | 536.7 | 1.48 ± 0.03 |
+| `dust -d0 ~` | 592.1 ± 15.5 | 567.8 | 626.7 | 1.67 ± 0.05 |
+| `gdu -npc ~` | 711.4 ± 9.8 | 702.9 | 734.8 | 2.00 ± 0.04 |
+| `gdu -gnpc ~` | 847.7 ± 11.1 | 827.2 | 861.2 | 2.39 ± 0.04 |
+| `du -hs ~` | 1387.0 ± 6.5 | 1379.9 | 1398.3 | 3.91 ± 0.05 |
+| `duc index ~` | 1638.3 ± 5.1 | 1630.7 | 1646.7 | 4.62 ± 0.05 |
+| `ncdu -0 -o /dev/null ~` | 2348.9 ± 9.1 | 2330.5 | 2364.5 | 6.62 ± 0.08 |
 
 ## Alternatives
 
@@ -270,3 +278,4 @@ Filesystem cache was cleared using `sync; echo 3 | sudo tee /proc/sys/vm/drop_ca
 * [diskus](https://github.com/sharkdp/diskus) - Very simple but very fast tool written in Rust
 * [duc](https://duc.zevv.nl/) - Collection of tools with many possibilities for inspecting and visualising disk usage
 * [dust](https://github.com/bootandy/dust) - Tool written in Rust showing tree like structures of disk usage
+* [pdu](https://github.com/KSXGitHub/parallel-disk-usage) - Tool written in Rust showing tree like structures of disk usage
diff --git a/cmd/gdu/app/app.go b/cmd/gdu/app/app.go
index 63afcd8..445d667 100644
--- a/cmd/gdu/app/app.go
+++ b/cmd/gdu/app/app.go
@@ -65,6 +65,7 @@ type Flags struct {
 	UseSIPrefix       bool     `yaml:"use-si-prefix"`
 	NoPrefix          bool     `yaml:"no-prefix"`
 	WriteConfig       bool     `yaml:"-"`
+	ChangeCwd         bool     `yaml:"change-cwd"`
 	Style             Style    `yaml:"style"`
 	Sorting           Sorting  `yaml:"sorting"`
 }
@@ -240,6 +241,11 @@ func (a *App) createUI() (UI, error) {
 				ui.SetDefaultSorting(a.Flags.Sorting.By, a.Flags.Sorting.Order)
 			})
 		}
+		if a.Flags.ChangeCwd != false {
+			opts = append(opts, func(ui *tui.UI) {
+				ui.SetChangeCwdFn(os.Chdir)
+			})
+		}
 
 		ui = tui.CreateUI(
 			a.TermApp,
diff --git a/cmd/gdu/main.go b/cmd/gdu/main.go
index 5ac5e19..0c28296 100644
--- a/cmd/gdu/main.go
+++ b/cmd/gdu/main.go
@@ -171,10 +171,6 @@ func runE(command *cobra.Command, args []string) error {
 		if err != nil {
 			return fmt.Errorf("Error creating screen: %w", err)
 		}
-		err = screen.Init()
-		if err != nil {
-			return fmt.Errorf("Error initializing screen: %w", err)
-		}
 		defer screen.Clear()
 		defer screen.Fini()
 
diff --git a/go.mod b/go.mod
index 5c3b579..f9b8a14 100644
--- a/go.mod
+++ b/go.mod
@@ -3,31 +3,31 @@ module github.com/dundee/gdu/v5
 go 1.18
 
 require (
-	github.com/fatih/color v1.13.0
-	github.com/gdamore/tcell/v2 v2.5.3
+	github.com/fatih/color v1.15.0
+	github.com/gdamore/tcell/v2 v2.6.0
 	github.com/maruel/natural v1.1.0
-	github.com/mattn/go-isatty v0.0.16
+	github.com/mattn/go-isatty v0.0.19
 	github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
-	github.com/rivo/tview v0.0.0-20220916081518-2e69b7385a37
-	github.com/sirupsen/logrus v1.9.0
-	github.com/spf13/cobra v1.5.0
+	github.com/rivo/tview v0.0.0-20230530133550-8bd761dda819
+	github.com/sirupsen/logrus v1.9.2
+	github.com/spf13/cobra v1.7.0
 	github.com/stretchr/testify v1.8.0
-	golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41
+	golang.org/x/sys v0.8.0
 	gopkg.in/yaml.v3 v3.0.1
 )
 
 require (
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/gdamore/encoding v1.0.0 // indirect
-	github.com/inconshreveable/mousetrap v1.0.1 // indirect
+	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/kr/pretty v0.3.0 // indirect
 	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
-	github.com/mattn/go-runewidth v0.0.13 // indirect
+	github.com/mattn/go-runewidth v0.0.14 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/rivo/uniseg v0.4.2 // indirect
+	github.com/rivo/uniseg v0.4.4 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
-	golang.org/x/text v0.3.7 // indirect
+	golang.org/x/term v0.8.0 // indirect
+	golang.org/x/text v0.9.0 // indirect
 	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
 )
diff --git a/go.sum b/go.sum
index 3b94c37..244b993 100644
--- a/go.sum
+++ b/go.sum
@@ -3,15 +3,14 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
-github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
+github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
 github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
 github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
-github.com/gdamore/tcell/v2 v2.5.3 h1:b9XQrT6QGbgI7JvZOJXFNczOQeIYbo8BfeSMzt2sAV0=
-github.com/gdamore/tcell/v2 v2.5.3/go.mod h1:wSkrPaXoiIWZqW/g7Px4xc79di6FTcpB8tvaKJ6uGBo=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
-github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg=
+github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
 github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
@@ -23,31 +22,30 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69
 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
 github.com/maruel/natural v1.1.0 h1:2z1NgP/Vae+gYrtC0VuvrTJ6U35OuyUqDdfluLqMWuQ=
 github.com/maruel/natural v1.1.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ=
-github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
-github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
+github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rivo/tview v0.0.0-20220916081518-2e69b7385a37 h1:cTzFg1FfTXwXuODi7Doz70hsW+dAye1OBwAFWHCqmww=
-github.com/rivo/tview v0.0.0-20220916081518-2e69b7385a37/go.mod h1:YX2wUZOcJGOIycErz2s9KvDaP0jnWwRCirQMPLPpQ+Y=
+github.com/rivo/tview v0.0.0-20230530133550-8bd761dda819 h1:qRMCGgwKl66uWe7Hnzl5bCvZlfrLNIxOx7K00j5XeNc=
+github.com/rivo/tview v0.0.0-20230530133550-8bd761dda819/go.mod h1:nVwGv4MP47T0jvlk7KuTTjjuSmrGO4JF0iaiNt4bufE=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
-github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
-github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
+github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
 github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
-github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
-github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
+github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
+github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
+github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -56,28 +54,46 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc=
-golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc=
-golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/tui/keys.go b/tui/keys.go
index 945d1ab..6c4dc57 100644
--- a/tui/keys.go
+++ b/tui/keys.go
@@ -2,12 +2,18 @@ package tui
 
 import (
 	"fmt"
+	"syscall"
 
 	"github.com/dundee/gdu/v5/pkg/fs"
 	"github.com/gdamore/tcell/v2"
+	"github.com/rivo/tview"
 )
 
 func (ui *UI) keyPressed(key *tcell.EventKey) *tcell.EventKey {
+	if ui.handleCtrlZ(key) == nil {
+		return nil
+	}
+
 	if ui.pages.HasPage("file") {
 		return key // send event to primitive
 	}
@@ -23,7 +29,7 @@ func (ui *UI) keyPressed(key *tcell.EventKey) *tcell.EventKey {
 	if key == nil {
 		return nil
 	}
-	key = ui.handleBreakingActions(key)
+	key = ui.handleQuit(key)
 	if key == nil {
 		return nil
 	}
@@ -31,19 +37,31 @@ func (ui *UI) keyPressed(key *tcell.EventKey) *tcell.EventKey {
 	if ui.pages.HasPage("confirm") ||
 		ui.pages.HasPage("progress") ||
 		ui.pages.HasPage("deleting") ||
-		ui.pages.HasPage("emptying") ||
-		ui.pages.HasPage("help") {
+		ui.pages.HasPage("emptying") {
+		return key
+	}
+
+	key = ui.handleHelp(key)
+	if key == nil {
+		return nil
+	}
+
+	if ui.pages.HasPage("help") {
 		return key
 	}
 
+	key = ui.handleShell(key)
+	if key == nil {
+		return nil
+	}
+
 	key = ui.handleLeftRight(key)
 	if key == nil {
 		return nil
 	}
 
-	if key.Key() == tcell.KeyTab && ui.filteringInput != nil {
-		ui.filtering = true
-		ui.app.SetFocus(ui.filteringInput)
+	key = ui.handleFiltering(key)
+	if key == nil {
 		return nil
 	}
 
@@ -95,7 +113,26 @@ func (ui *UI) handleInfoPageEvents(key *tcell.EventKey) *tcell.EventKey {
 	return key
 }
 
-func (ui *UI) handleBreakingActions(key *tcell.EventKey) *tcell.EventKey {
+// handle ctrl+z job control
+func (ui *UI) handleCtrlZ(key *tcell.EventKey) *tcell.EventKey {
+	if key.Key() == tcell.KeyCtrlZ {
+		ui.app.Suspend(func() {
+			termApp := ui.app.(*tview.Application)
+			termApp.Lock()
+			defer termApp.Unlock()
+
+			err := syscall.Kill(syscall.Getpid(), syscall.SIGTSTP)
+			if err != nil {
+				ui.showErr("Error sending STOP signal", err)
+			}
+		})
+		return nil
+	}
+
+	return key
+}
+
+func (ui *UI) handleQuit(key *tcell.EventKey) *tcell.EventKey {
 	switch key.Rune() {
 	case 'Q':
 		ui.app.Stop()
@@ -104,16 +141,27 @@ func (ui *UI) handleBreakingActions(key *tcell.EventKey) *tcell.EventKey {
 	case 'q':
 		ui.app.Stop()
 		return nil
-	case 'b':
-		ui.spawnShell()
-		return nil
-	case '?':
+	}
+	return key
+}
+
+func (ui *UI) handleHelp(key *tcell.EventKey) *tcell.EventKey {
+	if key.Rune() == '?' {
 		if ui.pages.HasPage("help") {
 			ui.pages.RemovePage("help")
 			ui.app.SetFocus(ui.table)
 			return nil
 		}
 		ui.showHelp()
+		return nil
+	}
+	return key
+}
+
+func (ui *UI) handleShell(key *tcell.EventKey) *tcell.EventKey {
+	if key.Rune() == 'b' {
+		ui.spawnShell()
+		return nil
 	}
 	return key
 }
@@ -131,6 +179,15 @@ func (ui *UI) handleLeftRight(key *tcell.EventKey) *tcell.EventKey {
 	return key
 }
 
+func (ui *UI) handleFiltering(key *tcell.EventKey) *tcell.EventKey {
+	if key.Key() == tcell.KeyTab && ui.filteringInput != nil {
+		ui.filtering = true
+		ui.app.SetFocus(ui.filteringInput)
+		return nil
+	}
+	return key
+}
+
 func (ui *UI) handleMainActions(key *tcell.EventKey) *tcell.EventKey {
 	switch key.Rune() {
 	case 'd':
diff --git a/tui/show.go b/tui/show.go
index a896940..7dcbd8c 100644
--- a/tui/show.go
+++ b/tui/show.go
@@ -4,9 +4,11 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/dundee/gdu/v5/build"
 	"github.com/gdamore/tcell/v2"
 	"github.com/rivo/tview"
+	log "github.com/sirupsen/logrus"
+
+	"github.com/dundee/gdu/v5/build"
 )
 
 const helpText = `     [::b]up/down, k/j    [white:black:-]Move cursor up/down
@@ -48,6 +50,15 @@ func (ui *UI) showDir() {
 	)
 
 	ui.currentDirPath = ui.currentDir.GetPath()
+
+	if ui.changeCwdFn != nil {
+		err := ui.changeCwdFn(ui.currentDirPath)
+		if err != nil {
+			log.Printf("error setting cwd: %s", err.Error())
+		}
+		log.Printf("changing cwd to %s", ui.currentDirPath)
+	}
+
 	ui.currentDirLabel.SetText("[::b] --- " +
 		tview.Escape(
 			strings.TrimPrefix(ui.currentDirPath, build.RootPathPrefix),
diff --git a/tui/tui.go b/tui/tui.go
index d82379f..a2186eb 100644
--- a/tui/tui.go
+++ b/tui/tui.go
@@ -45,6 +45,7 @@ type UI struct {
 	emptier                 func(fs.Item, fs.Item) error
 	getter                  device.DevicesInfoGetter
 	exec                    func(argv0 string, argv []string, envv []string) error
+	changeCwdFn             func(string) error
 	linkedItems             fs.HardLinkedItems
 	selectedTextColor       tcell.Color
 	selectedBackgroundColor tcell.Color
@@ -179,6 +180,12 @@ func (ui *UI) SetCurrentItemNameMaxLen(len int) {
 	ui.currentItemNameMaxLen = len
 }
 
+// SetChangeCwdFn sets function that can be used to change current working dir
+// during dir browsing
+func (ui *UI) SetChangeCwdFn(fn func(string) error) {
+	ui.changeCwdFn = fn
+}
+
 // StartUILoop starts tview application
 func (ui *UI) StartUILoop() error {
 	return ui.app.Run()


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 917c2c6..22a2700 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -12,7 +12,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
     - name: Install Go
-      uses: actions/setup-go@v2
+      uses: actions/setup-go@v4
       with:
         go-version: 1.18.x
     - name: Checkout code
@@ -31,7 +31,7 @@ jobs:
     steps:
     - name: Install Go
       if: success()
-      uses: actions/setup-go@v2
+      uses: actions/setup-go@v4
       with:
         go-version: ${{ matrix.go-version }}
     - name: Checkout code
@@ -44,7 +44,7 @@ jobs:
     steps:
     - name: Install Go
       if: success()
-      uses: actions/setup-go@v2
+      uses: actions/setup-go@v4
       with:
         go-version: 1.18.x
     - name: Checkout code
@@ -53,15 +53,8 @@ jobs:
       run: |
         go test -v -race -covermode=atomic -coverprofile=coverage.out ./...
     - name: Upload coverage report
-      uses: codecov/codecov-action@v2
+      uses: codecov/codecov-action@v3
       with:
         files: ./coverage.out
         fail_ci_if_error: true
         verbose: true
-    - name: Convert coverage.out to coverage.lcov
-      uses: jandelgado/gcov2lcov-action@v1.0.6
-    - name: Coveralls
-      uses: coverallsapp/github-action@v1.1.2
-      with:
-          github-token: ${{ secrets.github_token }}
-          path-to-lcov: coverage.lcov
diff --git a/cmd/gdu/app/app_test.go b/cmd/gdu/app/app_test.go
index 947f453..2aa5cf1 100644
--- a/cmd/gdu/app/app_test.go
+++ b/cmd/gdu/app/app_test.go
@@ -214,6 +214,24 @@ func TestAnalyzePathWithExport(t *testing.T) {
 	assert.Nil(t, err)
 }
 
+func TestAnalyzePathWithChdir(t *testing.T) {
+	fin := testdir.CreateTestDir()
+	defer fin()
+
+	out, err := runApp(
+		&Flags{
+			LogFile:   "/dev/null",
+			ChangeCwd: true,
+		},
+		[]string{"test_dir"},
+		true,
+		testdev.DevicesInfoGetterMock{},
+	)
+
+	assert.Empty(t, out)
+	assert.Nil(t, err)
+}
+
 func TestReadAnalysisFromFile(t *testing.T) {
 	out, err := runApp(
 		&Flags{LogFile: "/dev/null", InputFile: "../../../internal/testdata/test.json"},
diff --git a/internal/testapp/app.go b/internal/testapp/app.go
index f4d6757..5678fdc 100644
--- a/internal/testapp/app.go
+++ b/internal/testapp/app.go
@@ -10,22 +10,17 @@ import (
 )
 
 // CreateSimScreen returns tcell.SimulationScreen
-func CreateSimScreen(width, height int) tcell.SimulationScreen {
+func CreateSimScreen() tcell.SimulationScreen {
 	screen := tcell.NewSimulationScreen("UTF-8")
-	err := screen.Init()
-	if err != nil {
-		panic(err)
-	}
-	screen.SetSize(width, height)
-
 	return screen
 }
 
 // CreateTestAppWithSimScreen returns app with simulation screen for tests
 func CreateTestAppWithSimScreen(width, height int) (*tview.Application, tcell.SimulationScreen) {
 	app := tview.NewApplication()
-	screen := CreateSimScreen(width, height)
+	screen := CreateSimScreen()
 	app.SetScreen(screen)
+	screen.SetSize(width, height)
 	return app, screen
 }
 
diff --git a/tui/actions_test.go b/tui/actions_test.go
index 325c71f..59c36a5 100644
--- a/tui/actions_test.go
+++ b/tui/actions_test.go
@@ -2,6 +2,7 @@ package tui
 
 import (
 	"bytes"
+	"errors"
 	"os"
 	"testing"
 
@@ -55,7 +56,7 @@ func TestShowDevicesBW(t *testing.T) {
 }
 
 func TestDeviceSelected(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -105,7 +106,7 @@ func TestAnalyzePathWithParentDir(t *testing.T) {
 		Files: make([]fs.Item, 0, 1),
 	}
 
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -131,7 +132,7 @@ func TestAnalyzePathWithParentDir(t *testing.T) {
 }
 
 func TestReadAnalysis(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	input, err := os.OpenFile("../internal/testdata/test.json", os.O_RDONLY, 0644)
@@ -154,7 +155,7 @@ func TestReadAnalysis(t *testing.T) {
 }
 
 func TestReadAnalysisWithWrongFile(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	input, err := os.OpenFile("../internal/testdata/wrong.json", os.O_RDONLY, 0644)
@@ -177,7 +178,7 @@ func TestReadAnalysisWithWrongFile(t *testing.T) {
 }
 
 func TestViewDirContents(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -200,7 +201,7 @@ func TestViewDirContents(t *testing.T) {
 }
 
 func TestViewFileWithoutCurrentDir(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -213,7 +214,7 @@ func TestViewFileWithoutCurrentDir(t *testing.T) {
 }
 
 func TestViewContentsOfNotExistingFile(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -243,7 +244,7 @@ func TestViewContentsOfNotExistingFile(t *testing.T) {
 func TestViewFile(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -271,10 +272,80 @@ func TestViewFile(t *testing.T) {
 	assert.Equal(t, 'j', event.Rune())
 }
 
+func TestChangeCwd(t *testing.T) {
+	fin := testdir.CreateTestDir()
+	defer fin()
+	simScreen := testapp.CreateSimScreen()
+	defer simScreen.Fini()
+	cwd := ""
+
+	opt := func(ui *UI) {
+		ui.SetChangeCwdFn(func(p string) error {
+			cwd = p
+			return nil
+		})
+	}
+	app := testapp.CreateMockedApp(true)
+	ui := CreateUI(app, simScreen, &bytes.Buffer{}, false, true, false, false, false, opt)
+	ui.done = make(chan struct{})
+	err := ui.AnalyzePath("test_dir", nil)
+	assert.Nil(t, err)
+
+	<-ui.done // wait for analyzer
+
+	for _, f := range ui.app.(*testapp.MockedApp).GetUpdateDraws() {
+		f()
+	}
+
+	assert.Equal(t, "test_dir", ui.currentDir.GetName())
+
+	ui.table.Select(0, 0)
+	ui.keyPressed(tcell.NewEventKey(tcell.KeyRight, 'l', 0))
+	ui.table.Select(1, 0)
+	ui.keyPressed(tcell.NewEventKey(tcell.KeyRight, 'l', 0))
+
+	assert.Equal(t, cwd, "test_dir/nested/subnested")
+}
+
+func TestChangeCwdWithErr(t *testing.T) {
+	fin := testdir.CreateTestDir()
+	defer fin()
+	simScreen := testapp.CreateSimScreen()
+	defer simScreen.Fini()
+	cwd := ""
+
+	opt := func(ui *UI) {
+		ui.SetChangeCwdFn(func(p string) error {
+			cwd = p
+			return errors.New("failed")
+		})
+	}
+	app := testapp.CreateMockedApp(true)
+	ui := CreateUI(app, simScreen, &bytes.Buffer{}, false, true, false, false, false, opt)
+	ui.done = make(chan struct{})
+	err := ui.AnalyzePath("test_dir", nil)
+	assert.Nil(t, err)
+
+	<-ui.done // wait for analyzer
+
+	for _, f := range ui.app.(*testapp.MockedApp).GetUpdateDraws() {
+		f()
+	}
+
+	assert.Equal(t, "test_dir", ui.currentDir.GetName())
+
+	ui.table.Select(0, 0)
+	ui.keyPressed(tcell.NewEventKey(tcell.KeyRight, 'l', 0))
+	ui.table.Select(1, 0)
+	ui.keyPressed(tcell.NewEventKey(tcell.KeyRight, 'l', 0))
+
+	assert.Equal(t, cwd, "test_dir/nested/subnested")
+}
+
 func TestShowInfo(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -304,7 +375,7 @@ func TestShowInfo(t *testing.T) {
 func TestShowInfoBW(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -334,7 +405,7 @@ func TestShowInfoBW(t *testing.T) {
 func TestShowInfoWithHardlinks(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -376,7 +447,7 @@ func TestShowInfoWithHardlinks(t *testing.T) {
 func TestShowInfoWithoutCurrentDir(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -391,7 +462,7 @@ func TestShowInfoWithoutCurrentDir(t *testing.T) {
 func TestExitViewFile(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
diff --git a/tui/filter_test.go b/tui/filter_test.go
index 1747438..562a580 100644
--- a/tui/filter_test.go
+++ b/tui/filter_test.go
@@ -13,7 +13,7 @@ import (
 )
 
 func TestFiltering(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -47,7 +47,7 @@ func TestFiltering(t *testing.T) {
 }
 
 func TestFilteringWithoutCurrentDir(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -63,7 +63,7 @@ func TestFilteringWithoutCurrentDir(t *testing.T) {
 func TestSwitchToTable(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -106,7 +106,7 @@ func TestSwitchToTable(t *testing.T) {
 func TestExitFiltering(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
diff --git a/tui/format_test.go b/tui/format_test.go
index 729cd5b..9b9fa8b 100644
--- a/tui/format_test.go
+++ b/tui/format_test.go
@@ -10,7 +10,7 @@ import (
 )
 
 func TestFormatSize(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -27,7 +27,7 @@ func TestFormatSize(t *testing.T) {
 }
 
 func TestFormatSizeDec(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -44,7 +44,7 @@ func TestFormatSizeDec(t *testing.T) {
 }
 
 func TestFormatCount(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -57,7 +57,7 @@ func TestFormatCount(t *testing.T) {
 }
 
 func TestEscapeName(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -79,7 +79,7 @@ func TestEscapeName(t *testing.T) {
 }
 
 func TestMarked(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
diff --git a/tui/keys_test.go b/tui/keys_test.go
index 0b29043..eb52d13 100644
--- a/tui/keys_test.go
+++ b/tui/keys_test.go
@@ -17,7 +17,7 @@ import (
 )
 
 func TestShowHelp(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -29,7 +29,7 @@ func TestShowHelp(t *testing.T) {
 }
 
 func TestCloseHelp(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -44,7 +44,7 @@ func TestCloseHelp(t *testing.T) {
 }
 
 func TestCloseHelpWithQuestionMark(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -59,7 +59,7 @@ func TestCloseHelpWithQuestionMark(t *testing.T) {
 }
 
 func TestKeyWhileDeleting(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -73,7 +73,7 @@ func TestKeyWhileDeleting(t *testing.T) {
 }
 
 func TestLeftRightKeyWhileConfirm(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -91,7 +91,7 @@ func TestLeftRightKeyWhileConfirm(t *testing.T) {
 func TestMoveLeftRight(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -137,7 +137,7 @@ func TestMoveLeftRight(t *testing.T) {
 func TestMoveRightOnDevice(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -168,7 +168,7 @@ func TestMoveRightOnDevice(t *testing.T) {
 }
 
 func TestStop(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -181,7 +181,7 @@ func TestStop(t *testing.T) {
 func TestStopWithPrintingPath(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -207,7 +207,7 @@ func TestStopWithPrintingPath(t *testing.T) {
 func TestSpawnShell(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -237,7 +237,7 @@ func TestSpawnShell(t *testing.T) {
 func TestSpawnShellWithoutDir(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -259,7 +259,7 @@ func TestSpawnShellWithoutDir(t *testing.T) {
 func TestSpawnShellWithWrongDir(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -284,7 +284,7 @@ func TestSpawnShellWithWrongDir(t *testing.T) {
 func TestSpawnShellWithError(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -307,7 +307,7 @@ func TestSpawnShellWithError(t *testing.T) {
 }
 
 func TestShowConfirm(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -330,10 +330,14 @@ func TestShowConfirm(t *testing.T) {
 	ui.keyPressed(tcell.NewEventKey(tcell.KeyRune, 'd', 0))
 
 	assert.True(t, ui.pages.HasPage("confirm"))
+
+	ui.keyPressed(tcell.NewEventKey(tcell.KeyRune, '?', 0))
+
+	assert.False(t, ui.pages.HasPage("help"))
 }
 
 func TestDeleteEmpty(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -345,7 +349,7 @@ func TestDeleteEmpty(t *testing.T) {
 }
 
 func TestMarkEmpty(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -359,7 +363,7 @@ func TestMarkEmpty(t *testing.T) {
 func TestDelete(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -395,7 +399,7 @@ func TestDelete(t *testing.T) {
 func TestDeleteMarked(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -433,7 +437,7 @@ func TestDeleteMarked(t *testing.T) {
 func TestDeleteParent(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -463,7 +467,7 @@ func TestDeleteParent(t *testing.T) {
 func TestMarkParent(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -493,7 +497,7 @@ func TestMarkParent(t *testing.T) {
 func TestEmptyDir(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -530,7 +534,7 @@ func TestEmptyDir(t *testing.T) {
 func TestMarkedEmptyDir(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -569,7 +573,7 @@ func TestMarkedEmptyDir(t *testing.T) {
 func TestEmptyFile(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -610,7 +614,7 @@ func TestEmptyFile(t *testing.T) {
 func TestMarkedEmptyFile(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -651,7 +655,7 @@ func TestMarkedEmptyFile(t *testing.T) {
 }
 
 func TestSortByApparentSize(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -675,7 +679,7 @@ func TestSortByApparentSize(t *testing.T) {
 }
 
 func TestShowFileCount(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -699,7 +703,7 @@ func TestShowFileCount(t *testing.T) {
 }
 
 func TestShowFileCountBW(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -723,7 +727,7 @@ func TestShowFileCountBW(t *testing.T) {
 }
 
 func TestShowMtime(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -747,7 +751,7 @@ func TestShowMtime(t *testing.T) {
 }
 
 func TestShowMtimeBW(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -771,7 +775,7 @@ func TestShowMtimeBW(t *testing.T) {
 }
 
 func TestShowRelativeBar(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -809,7 +813,7 @@ func TestRescan(t *testing.T) {
 		},
 	}
 
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -836,7 +840,7 @@ func TestRescan(t *testing.T) {
 }
 
 func TestSorting(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -867,7 +871,7 @@ func TestSorting(t *testing.T) {
 func TestShowFile(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -894,7 +898,7 @@ func TestShowFile(t *testing.T) {
 func TestShowInfoAndMoveAround(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
diff --git a/tui/mouse_test.go b/tui/mouse_test.go
index 8524696..12980e8 100644
--- a/tui/mouse_test.go
+++ b/tui/mouse_test.go
@@ -16,7 +16,7 @@ import (
 func TestDoubleClick(t *testing.T) {
 	fin := testdir.CreateTestDir()
 	defer fin()
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -50,7 +50,7 @@ func TestDoubleClick(t *testing.T) {
 }
 
 func TestScroll(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -76,7 +76,7 @@ func TestScroll(t *testing.T) {
 }
 
 func TestScrollWhenPageOpened(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -102,7 +102,7 @@ func TestScrollWhenPageOpened(t *testing.T) {
 }
 
 func TestEmptyEvent(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -114,7 +114,7 @@ func TestEmptyEvent(t *testing.T) {
 }
 
 func TestMouseMove(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
diff --git a/tui/sort_test.go b/tui/sort_test.go
index d0a8528..ff29af4 100644
--- a/tui/sort_test.go
+++ b/tui/sort_test.go
@@ -124,7 +124,7 @@ func TestSetSorting(t *testing.T) {
 }
 
 func TestSetDEfaultSorting(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	var opts []Option
@@ -184,7 +184,7 @@ func TestSortDevicesByUsedSize(t *testing.T) {
 }
 
 func getAnalyzedPathWithSorting(sortBy string, sortOrder string, apparentSize bool) *UI {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
diff --git a/tui/tui_test.go b/tui/tui_test.go
index 4c2a3e1..9a5a584 100644
--- a/tui/tui_test.go
+++ b/tui/tui_test.go
@@ -55,6 +55,8 @@ func TestFooter(t *testing.T) {
 
 	b, _, _ := simScreen.GetContents()
 
+	printScreen(simScreen)
+
 	text := []byte(" Total disk usage: 4.0 KiB Apparent size: 2 B Items: 1")
 	for i, r := range b {
 		if i >= len(text) {
@@ -121,7 +123,7 @@ func TestHelpBw(t *testing.T) {
 }
 
 func TestAppRun(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(false)
@@ -133,7 +135,7 @@ func TestAppRun(t *testing.T) {
 }
 
 func TestAppRunWithErr(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -158,7 +160,7 @@ func TestRescanDir(t *testing.T) {
 		},
 	}
 
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 	app := testapp.CreateMockedApp(true)
 	ui := CreateUI(app, simScreen, &bytes.Buffer{}, false, true, false, false, false)
@@ -206,7 +208,7 @@ func TestFileSelected(t *testing.T) {
 }
 
 func TestSelectedWithoutCurrentDir(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -232,7 +234,7 @@ func TestBeforeDraw(t *testing.T) {
 }
 
 func TestIgnorePaths(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -372,7 +374,7 @@ func TestDeleteMarkedWithErr(t *testing.T) {
 }
 
 func TestShowErr(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -384,7 +386,7 @@ func TestShowErr(t *testing.T) {
 }
 
 func TestShowErrBW(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -401,7 +403,7 @@ func TestMin(t *testing.T) {
 }
 
 func TestSetSelectedBackgroundColor(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -413,7 +415,7 @@ func TestSetSelectedBackgroundColor(t *testing.T) {
 }
 
 func TestSetSelectedTextColor(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -425,7 +427,7 @@ func TestSetSelectedTextColor(t *testing.T) {
 }
 
 func TestSetCurrentItemNameMaxLen(t *testing.T) {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)
@@ -467,7 +469,7 @@ func getDevicesInfoMock() device.DevicesInfoGetter {
 }
 
 func getAnalyzedPathMockedApp(t *testing.T, useColors, apparentSize bool, mockedAnalyzer bool) *UI {
-	simScreen := testapp.CreateSimScreen(50, 50)
+	simScreen := testapp.CreateSimScreen()
 	defer simScreen.Fini()
 
 	app := testapp.CreateMockedApp(true)