cetus 0.1.41 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +61 -29
- data/bin/cetus +166 -178
- data/cetus.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 354100c7054b31bc96f5bcc0a34056b68dcb061181467f0555443e340eac7922
|
4
|
+
data.tar.gz: 66f325607b440d2ebc476246b136f8c8e7d7e70a76cd27822c4abb56ff26f44f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c497713cbae448bdac329afa7f030046ad889f1a7053ce5e0c6debd55d60649107fca9b7d697193f6e7bbcbc2f028902c29c512cfc04008c75ed77450e73a6f9
|
7
|
+
data.tar.gz: d811607e119d64186c1c49b38e6d23c0e643c20a0fe9cafe95c83ab8144157a2e6f152e3039fbc441c3e4bca956d44fc445d5ea59eedd1cfdc38ddf6fd4d43cf
|
data/README.md
CHANGED
@@ -1,23 +1,31 @@
|
|
1
1
|
cetus
|
2
2
|
=====
|
3
3
|
|
4
|
-
|
4
|
+
Lightning-fast file navigator.
|
5
5
|
|
6
|
-
|
6
|
+
Open or page a file using hotkeys, rather than pressing ARROW keys repetitively (although that is supported also.)
|
7
7
|
|
8
|
-
|
9
|
-
2019-03-26 - Reading up 'LS_COLORS' and coloring filenames. v0.1.30
|
10
|
-
2019-03-24 - Major refactoring and cleanup. v 0.1.29
|
11
|
-
2019-03-04 - q is quit key, not Q
|
12
|
-
- show directories first, then files.
|
13
|
-
- trying not to pollute main screen/terminal with listings (i.e. use alt screen)
|
14
|
-
- C-s to select (toggle) current file
|
8
|
+
Many file actions are supported.
|
15
9
|
|
16
|
-
|
17
|
-
Also, pressing RIGHT ARROW on a file with open the file.
|
18
|
-
Previously RIGHT and LEFT arrows would move to next or previous columns, i have put this on left and right square bracket.
|
10
|
+
Scripts may be executed for selected files thus extending functionality.
|
19
11
|
|
20
|
-
|
12
|
+
|
13
|
+
Tested with ruby 2.6
|
14
|
+
|
15
|
+
|
16
|
+
### Latest changes:
|
17
|
+
|
18
|
+
* 2019-04-23 - Major cleanup and rewrite, once again show highlighted row. V 0.2.0
|
19
|
+
* 2019-03-26 - Reading up 'LS_COLORS' and coloring filenames. v0.1.30
|
20
|
+
* 2019-03-24 - Major refactoring and cleanup. v 0.1.29
|
21
|
+
* 2019-03-04 - q is quit key, not Q
|
22
|
+
* show directories first, then files.
|
23
|
+
* C-s to select (toggle) current file
|
24
|
+
|
25
|
+
* 2018-03-12 - now using LEFT and RIGHT arrow keys to go down into a directory, or up to higher directory.
|
26
|
+
* pressing RIGHT ARROW on a file will open the file.
|
27
|
+
|
28
|
+
* Previously RIGHT and LEFT arrows would move to next or previous columns, i have put this on left and right square bracket.
|
21
29
|
|
22
30
|
|
23
31
|
## Selecting a file
|
@@ -27,22 +35,26 @@ There are two ways of selecting a file.
|
|
27
35
|
1. Pressing C-s on a file.
|
28
36
|
2. Use hotkey (on left of file) to select without having to navigate.
|
29
37
|
|
30
|
-
While using C-s marks a file as selected, pressing the hotkey will either open
|
38
|
+
While using C-s marks a file as selected, OTOH pressing the hotkey will either open
|
31
39
|
the file using PAGER or EDITOR depending on current mode.
|
32
40
|
|
33
41
|
## Multiple Selection of files
|
34
42
|
|
35
|
-
1. Press C-s on multiple files.
|
36
|
-
|
43
|
+
1. Press C-s on multiple files. '*' toggles between multiple and single select mode.
|
44
|
+
|
45
|
+
2. Press `*` (asterisk) to enter multiple select mode.
|
37
46
|
Now press the hotkey (left of file) to select it.
|
38
47
|
|
48
|
+
3. Visual Mode. Press `Ctrl-Space` to enter visual/range select. Now move the arrow keys
|
49
|
+
up or down to select. Press `Ctrl-Space` again to end selection. Several ranges may be selected.
|
50
|
+
|
39
51
|
To execute an action on multiple (or single) files, you may press `C-x` and choose
|
40
|
-
an action such as move
|
52
|
+
an action such as move, delete, rename, copy, etc.
|
41
53
|
|
42
54
|
You may also select all files with the same extension as current file. Invoke the
|
43
55
|
filter menu using Tilde-F. Now select `x` or `:extension`.
|
44
56
|
|
45
|
-
`Tilde-
|
57
|
+
`Tilde-s` is the selection menu. M-a is select all, M-A is unselect all.
|
46
58
|
|
47
59
|
## Moving multiple files
|
48
60
|
|
@@ -52,7 +64,7 @@ Now there are two ways to move selected files to another directory.
|
|
52
64
|
|
53
65
|
1. Press `C-x m` and type the name of the directory at the prompt.
|
54
66
|
|
55
|
-
2.
|
67
|
+
2. Or navigate to the target directory, and then press `C-x m` and type "." at the prompt.
|
56
68
|
|
57
69
|
## Copying files to another directory.
|
58
70
|
|
@@ -60,10 +72,31 @@ Use the same procedure as for moving files but press `C-x c`
|
|
60
72
|
|
61
73
|
1. Press `C-x c` and then type the name of the target directory at the prompt.
|
62
74
|
|
63
|
-
2.
|
75
|
+
2. Select files, then navigate to the target directory, and press `C-x c`, and type '.' at the prompt.
|
76
|
+
|
77
|
+
3. If copying a file, to the same directory, or if the file already exists, a unique name will be suggested (numeric suffix).
|
78
|
+
|
79
|
+
## Scripts
|
80
|
+
|
81
|
+
* Scripts access selected files and can take actions on them. Examples are scripts that remove spaces and brackets from selected files, or create a directory with the selected files, encrypt files, archive files, convert file format using `ffmpeg`, etc.
|
64
82
|
|
83
|
+
* Scripts are located in the CONFIG folder, under `cetus/scripts`. Usually this is `.config` but can be configured via XDG_CONFIG_HOME.
|
65
84
|
|
66
|
-
|
85
|
+
* Selected files are located in `~/tmp/selected_files`
|
86
|
+
|
87
|
+
* Scripts are also passed the filename under the cursor, and may act on it if no file has been selected.
|
88
|
+
|
89
|
+
* Currently, scripts don't pass any messages back to the application. Suggestions welcome.
|
90
|
+
|
91
|
+
## Generators
|
92
|
+
|
93
|
+
Generators are used to generate a list of file names or directories that can be used for navigation, or paging/editing or other file actions.
|
94
|
+
|
95
|
+
For example, a generator could generate filenames from `.viminfo` or `z` or `autojump`
|
96
|
+
|
97
|
+
## More
|
98
|
+
|
99
|
+
Fork of `lyra` with a different hotkey idea. Use this for quickly navigating your file system using hotkeys
|
67
100
|
and bookmarks, and executing commands on single or multiple files easily.
|
68
101
|
|
69
102
|
See https://github.com/rkumar/lyra for detailed info of usage.
|
@@ -76,11 +109,6 @@ only 60 files can be shown at a time on a screen.
|
|
76
109
|
|
77
110
|
It also maps z and Z which are at a convenient location. If there are more than 24 then za-zz are used. if the file exceed even that, then the range Za-ZZ is used. This means that larger screens will be filled with file names (upto ROWS * 3), and the user can even specify the number of columns. I've tried with 6. The remainder files gets an index of "&rt;" (right arrow) which means that if one presses right arrow then the indexing starts from the second column. RIGHT and LEFT arrow can be used to move indexing.
|
78
111
|
|
79
|
-
Experimentally added cursor movements which currently is only used if you get into a so-called visual mode, by pressing C-Space, moving up and down arrow and C-d and C-b will start adding to selection.
|
80
|
-
I did this since I was selecting quite a few files to delete in some old directory and would have liked some range delete. One can, of course, select files for a regex by pressing "/" giving a regex, and then using M-a to select all. Clear selection with M-A (Alt-Shift-a).
|
81
|
-
|
82
|
-
The cursor position shows up as a greater than sign, I hope not to implement all of zfm here. It's mainly used only to select multiple files that are contiguous.
|
83
|
-
|
84
112
|
|
85
113
|
Press C-x to execute actions on selected files. A menu of actions is displayed.
|
86
114
|
Or Press one of several commands after selecting files such as "D" for delete, or "M" to use your man-pager.
|
@@ -90,16 +118,20 @@ You can bind other capital letters to any external command. If there are selecte
|
|
90
118
|
|
91
119
|
The rest is similar to lyra. Some key points are highlighted here.
|
92
120
|
|
93
|
-
* Create bookmarks for often used directories using Alt-m. Then access them using single-quote and
|
121
|
+
* Create bookmarks for often used directories using Alt-m. Then access them using single-quote and character.
|
94
122
|
You have to be inside the directory when saving a new bookmark. e.g. `'P`. This is a fast way of jumping directories. I've got "P" mapped to projects, and "Z" to zfm, and so forth.
|
95
123
|
|
96
|
-
* Single-quote and
|
124
|
+
* Single-quote and letter jumps to the first file starting with given letter. e.g. `'s`
|
125
|
+
* Double-quote and letter jumps to the first file starting with given letter. e.g. `"s`
|
126
|
+
|
127
|
+
* Numbers for bookmarks. The starting directory is automatically bookmarked as '0'.
|
128
|
+
Pressing '0' from anywhere brings us to the starting directory. Pressing a number will create a bookmark for the current directory, or take us to that directory, if a bookmark exists. This is a quick way to make bookmarks and jump to them. Useful when moving or copying files.
|
97
129
|
|
98
130
|
* Space-bar pages, also Alt n and p. Ctrl-d and Ctrl-b goes down 10 rows.
|
99
131
|
|
100
132
|
* Backtick is the main menu, which has options for sorting, filtering, seeing often used dirs and files, choosing from dirs in the `z` database, choosing used files from the `.viminfo` file, etc.
|
101
133
|
|
102
|
-
Other than using bookmarks, you can jump quickly to other directories or open files using BACKTICK and the
|
134
|
+
Other than using bookmarks, you can jump quickly to other directories or open files using BACKTICK and the relevant option which should become part of muscle memory very fast.
|
103
135
|
|
104
136
|
* Use Alt-d and Alt-f to see used directories and used files. Used directories are those dirs in which you have opened a file, not all dirs you've traversed. Certain directories are added to this list to make it more useful such as GEM_HOME, RUBYPATH, GEM_PATH, RUBYLIB, PYTHONPATH and PYTHONHOME.
|
105
137
|
|
data/bin/cetus
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
# Author: rkumar http://github.com/rkumar/cetus/
|
9
9
|
# Date: 2013-02-17 - 17:48
|
10
10
|
# License: GPL
|
11
|
-
# Last update: 2019-04-
|
11
|
+
# Last update: 2019-04-24 13:56
|
12
12
|
# --------------------------------------------------------------------------- #
|
13
13
|
# cetus.rb Copyright (C) 2012-2019 rahul kumar
|
14
14
|
# == CHANGELOG
|
@@ -40,7 +40,7 @@ now = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
|
40
40
|
# alias c=~/bin/cetus.rb
|
41
41
|
# c
|
42
42
|
|
43
|
-
VERSION = '0.
|
43
|
+
VERSION = '0.2.0.0'
|
44
44
|
CONFIG_PATH = ENV['XDG_CONFIG_HOME'] || File.join(ENV['HOME'], '.config')
|
45
45
|
CONFIG_FILE = "#{CONFIG_PATH}/cetus/conf.yml"
|
46
46
|
|
@@ -333,6 +333,7 @@ PAGER_COMMAND = {
|
|
333
333
|
text: 'most',
|
334
334
|
image: 'open',
|
335
335
|
zip: 'tar ztvf %% | most',
|
336
|
+
sqlite: 'sqlite3 %% .schema | most',
|
336
337
|
unknown: 'open'
|
337
338
|
}.freeze
|
338
339
|
@dir_position = {}
|
@@ -348,6 +349,8 @@ PAGER_COMMAND = {
|
|
348
349
|
@selected_files_escaped_flag = false
|
349
350
|
@keys_to_clear = nil
|
350
351
|
@ignore_case = true
|
352
|
+
@highlight_row_flag = true # false
|
353
|
+
@debug_flag = false
|
351
354
|
|
352
355
|
# See toggle_value
|
353
356
|
# we need to set these on startup
|
@@ -365,7 +368,8 @@ PAGER_COMMAND = {
|
|
365
368
|
selection_mode: false, # typing hint adds to selection, does not open
|
366
369
|
debug_flag: false,
|
367
370
|
toggle_filename_status_line: true,
|
368
|
-
instant_search: true
|
371
|
+
instant_search: true,
|
372
|
+
highlight_row_flag: @highlight_row_flag
|
369
373
|
}
|
370
374
|
# var is name of variable to be set
|
371
375
|
@options = {
|
@@ -385,6 +389,8 @@ BOLD = "\e[1m"
|
|
385
389
|
BOLD_OFF = "\e[22m"
|
386
390
|
RED = "\e[31m"
|
387
391
|
ON_RED = "\e[41m"
|
392
|
+
ON_GREEN = "\e[42m"
|
393
|
+
ON_YELLOW = "\e[43m"
|
388
394
|
GREEN = "\e[32m"
|
389
395
|
YELLOW = "\e[33m"
|
390
396
|
BLUE = "\e[1;34m"
|
@@ -393,6 +399,7 @@ CYAN = "\e[36m"
|
|
393
399
|
|
394
400
|
ON_BLUE = "\e[44m"
|
395
401
|
REVERSE = "\e[7m"
|
402
|
+
REVERSE_OFF = "\e[27m"
|
396
403
|
UNDERLINE = "\e[4m"
|
397
404
|
CURSOR_COLOR = REVERSE
|
398
405
|
|
@@ -562,14 +569,17 @@ end
|
|
562
569
|
def print_title
|
563
570
|
# print help line and version
|
564
571
|
print "#{GREEN}#{@help} #{BLUE}cetus #{VERSION}#{CLEAR}\n"
|
572
|
+
@current_dir ||= Dir.pwd
|
565
573
|
|
566
574
|
# print 1 of n files, sort order, filter etc details
|
567
|
-
@title ||=
|
575
|
+
@title ||= @current_dir.sub(ENV['HOME'], '~')
|
568
576
|
|
569
577
|
# Add bookmark next to name of dir, if exists
|
570
578
|
# FIXME This should not happen in other listings like find selected files etc
|
571
|
-
bm = @bookmarks.key(Dir.pwd)
|
572
|
-
|
579
|
+
# bm = @bookmarks.key(Dir.pwd)
|
580
|
+
# Display multiple bookmarks. Can be calculated on changing directory ?
|
581
|
+
bm = @bookmarks.select { |k, v| v == @current_dir }.keys.join(',')
|
582
|
+
bm = " ('#{bm})" if bm && bm != ''
|
573
583
|
|
574
584
|
fin = @sta + @viewport.size
|
575
585
|
fl = @view.size
|
@@ -589,8 +599,12 @@ def print_title
|
|
589
599
|
# don't exceed columns while printing
|
590
600
|
t = t[t.size - @gcols..-1] if t.size >= @gcols
|
591
601
|
|
592
|
-
print "#{BOLD}#{t}#{CLEAR}
|
593
|
-
|
602
|
+
print "#{BOLD}#{t}#{CLEAR}"
|
603
|
+
|
604
|
+
tput_cup(-1, @gcols - @hk.length - 2)
|
605
|
+
puts '[' + @hk + ']'
|
606
|
+
|
607
|
+
print "#{CURSOR_COLOR}EMPTY#{CLEAR}" if fl == 0
|
594
608
|
end
|
595
609
|
# ------------- end of print_title --------------------------------#
|
596
610
|
|
@@ -680,12 +694,8 @@ def draw_directory
|
|
680
694
|
clear_screen
|
681
695
|
print_title
|
682
696
|
|
683
|
-
# add hint and format the line
|
684
|
-
buff = format_array @viewport
|
685
|
-
|
686
697
|
# break viewport into as many columns as required
|
687
|
-
|
688
|
-
buff = columnate buff, @grows
|
698
|
+
buff = columnate @viewport, @grows
|
689
699
|
|
690
700
|
# starts printing array on line 3
|
691
701
|
buff.each { |line| print line, "\n" }
|
@@ -700,49 +710,45 @@ end
|
|
700
710
|
# XXX i am not sure how to highlight the bg without rewriting the text.
|
701
711
|
# I can get the filename but it has been truncated.
|
702
712
|
# I can get the earlier filename but the color has to be determined again.
|
703
|
-
# FIXME
|
704
|
-
#
|
705
|
-
|
706
|
-
|
707
|
-
|
713
|
+
# FIXME color of original hint lost if @highlight_row_flag.
|
714
|
+
# we can even get the filename, but it has been formatted and could
|
715
|
+
# be a long listing.
|
716
|
+
# color can be CURSOR_COLOR or CLEAR
|
717
|
+
# if CLEAR then we use original colors from get_formatted_filename.
|
718
|
+
# Otherwise we need to use CURSOR_COLOR in place of current color
|
719
|
+
def place_cursor color=CURSOR_COLOR
|
720
|
+
vps = @viewport.size
|
721
|
+
|
722
|
+
# empty directory
|
723
|
+
if vps == 0
|
724
|
+
tput_cup 0, 0
|
725
|
+
return
|
726
|
+
end
|
727
|
+
|
708
728
|
c = @cursor - @sta
|
729
|
+
wid = get_width vps, @grows
|
709
730
|
if c < @grows
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
731
|
+
rows = c
|
732
|
+
cols = 0
|
733
|
+
else
|
734
|
+
rows = c % @grows
|
735
|
+
cols = (c / @grows) * wid
|
715
736
|
end
|
716
|
-
|
717
|
-
rows = c % @grows
|
718
|
-
cols = (c / @grows) * wid
|
719
|
-
# system "tput cup #{rows + 2} #{cols}"
|
720
|
-
# print "\e[#{rows + 3};#{cols + 1}H"
|
737
|
+
|
721
738
|
tput_cup rows, cols
|
722
|
-
|
723
|
-
end
|
739
|
+
return unless @highlight_row_flag
|
724
740
|
|
725
|
-
#
|
726
|
-
|
727
|
-
def clear_cursor
|
728
|
-
return unless @old_cursor
|
741
|
+
color = nil if color == CLEAR # let it determine its own color
|
742
|
+
f = get_formatted_filename(c, wid)
|
729
743
|
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
end
|
739
|
-
wid = get_width @viewport.size, @grows
|
740
|
-
rows = @old_cursor % @grows
|
741
|
-
cols = (@old_cursor / @grows) * wid
|
742
|
-
# system "tput cup #{rows + 2} #{cols}"
|
743
|
-
tput_cup rows, cols
|
744
|
-
# print "#{CURSOR_COLOR}#{hint} >#{CLEAR}"
|
745
|
-
print "#{hint} "
|
744
|
+
f = color + f + CLEAR if color
|
745
|
+
|
746
|
+
# f = color + f if color # NOTE: this was causing 2 issues: color bleed onto
|
747
|
+
# status line and top line. And the highcolor of some rows would not go away.
|
748
|
+
# If REVERSE_OFF is used, then REVERSE_OFF must also be used
|
749
|
+
#
|
750
|
+
print f
|
751
|
+
tput_cup rows, cols # put it back at start
|
746
752
|
end
|
747
753
|
|
748
754
|
# place cursor on row and col taking first two rows into account
|
@@ -843,6 +849,7 @@ end
|
|
843
849
|
|
844
850
|
def set_bookmark key, dir=Dir.pwd
|
845
851
|
@bookmarks[key] = dir
|
852
|
+
@hk = @bookmarks.select { |k, _| k.match?(/[0-9]/) }.keys.sort.join('')
|
846
853
|
end
|
847
854
|
|
848
855
|
## write current dir to a file so we can ccd to it when exiting
|
@@ -872,13 +879,13 @@ end
|
|
872
879
|
|
873
880
|
## format date for file given stat
|
874
881
|
def date_format t
|
875
|
-
t.strftime '%Y/%m/%d'
|
882
|
+
t.strftime '%Y/%m/%d %H:%M:%S'
|
876
883
|
end
|
877
884
|
|
878
885
|
##
|
879
886
|
#
|
880
887
|
# print in columns
|
881
|
-
# ary - array of data (viewport, not view)
|
888
|
+
# ary - array of data (viewport, not view) with hint and mark, possibly long listing
|
882
889
|
# siz - how many lines should there be in one column
|
883
890
|
#
|
884
891
|
def columnate ary, siz
|
@@ -899,23 +906,7 @@ def columnate ary, siz
|
|
899
906
|
ctr = 0
|
900
907
|
while ctr < siz
|
901
908
|
|
902
|
-
f =
|
903
|
-
# f is not just filename but marker and hint
|
904
|
-
|
905
|
-
# check to see if we need to truncate
|
906
|
-
# 2019-03-18 - truncate from middle of string.
|
907
|
-
# 2019-03-24 - truncate and size to take care of color codes
|
908
|
-
# fsz = f.size
|
909
|
-
unformatted_len, = filename_len(f)
|
910
|
-
if unformatted_len > wid
|
911
|
-
# take the excess out from the center on both sides
|
912
|
-
f = truncate_formatted_filename(f, unformatted_len, wid)
|
913
|
-
|
914
|
-
elsif unformatted_len < wid
|
915
|
-
|
916
|
-
f << ' ' * (wid - unformatted_len)
|
917
|
-
|
918
|
-
end
|
909
|
+
f = get_formatted_filename(ix, wid)
|
919
910
|
|
920
911
|
# if already a value in that line, append to it
|
921
912
|
if buff[ctr]
|
@@ -944,13 +935,8 @@ def truncate_formatted_filename f, unformatted_len, wid
|
|
944
935
|
f = case @truncate_from
|
945
936
|
|
946
937
|
when :right
|
947
|
-
#
|
948
|
-
|
949
|
-
|
950
|
-
# We show exactly `wid` characters, but escapes are not displayed
|
951
|
-
# so add that may characters
|
952
|
-
# Also, remove 2 for $ and space
|
953
|
-
f[0..wid + sindex - 2] + "$ \e[m"
|
938
|
+
# FIXME: 2019-04-23 - do we need the control code at end ??
|
939
|
+
f[0..wid - 3] + "$ "
|
954
940
|
|
955
941
|
when :center
|
956
942
|
|
@@ -969,14 +955,6 @@ def truncate_formatted_filename f, unformatted_len, wid
|
|
969
955
|
# for single hints we need to add extra space
|
970
956
|
# there could be escape codes of varying length
|
971
957
|
sindex = f.index ' '
|
972
|
-
# if f[0] == "\e"
|
973
|
-
# mindex = f.index('m')
|
974
|
-
# hintsize = sindex - mindex - 1
|
975
|
-
# else
|
976
|
-
# hintsize = sindex - 1
|
977
|
-
# end
|
978
|
-
# f[0..sindex + 1] + '<' + f[-wid + hintsize..-1] + ' '
|
979
|
-
# @log.debug "XXX #{excess}: #{f} / #{wid}"
|
980
958
|
# 4 = 2 for literals, 2 to get ahead of sindex+1
|
981
959
|
f[0..sindex + 1] + '<' + f[sindex + 4 + excess..-1] + ' '
|
982
960
|
# in some cases 29/32 we are actually overlapping 2 parts above
|
@@ -985,75 +963,67 @@ def truncate_formatted_filename f, unformatted_len, wid
|
|
985
963
|
return f
|
986
964
|
end
|
987
965
|
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
966
|
+
# given index (in viewport) get a formatted, displayable rendition of the filename
|
967
|
+
# returns a String with hint, marks, filename (optional details) and color codes
|
968
|
+
# truncated to correct width.
|
969
|
+
def get_formatted_filename ix, wid
|
970
|
+
f = @viewport[ix]
|
992
971
|
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
972
|
+
ind = get_shortcut(ix)
|
973
|
+
mark = get_mark(f)
|
974
|
+
# Handle separator before enhanced file list.
|
975
|
+
# We do lose a shortcut
|
976
|
+
ind = cur = mark = '-' if f == SEPARATOR
|
977
|
+
prefix = "#{ind}#{mark}#{cur}"
|
997
978
|
|
998
|
-
#
|
999
|
-
|
1000
|
-
l = name.length
|
1001
|
-
return l if name[0] != "\e"
|
979
|
+
# fullname = f[0] == '~' ? File.expand_path(f) : f
|
980
|
+
color ||= color_for(f)
|
1002
981
|
|
1003
|
-
|
1004
|
-
index = name.index('m')
|
1005
|
-
eindex = name.rindex("\e")
|
1006
|
-
reall = eindex - index - 1
|
1007
|
-
return reall, l
|
1008
|
-
end
|
982
|
+
f = format_long_listing(f) if @long_listing
|
1009
983
|
|
1010
|
-
|
1011
|
-
|
1012
|
-
# buff = Array.new
|
1013
|
-
buff = Array.new(ary.size)
|
1014
|
-
return buff if ary.nil? || ary.empty?
|
984
|
+
# replace unprintable chars with ?
|
985
|
+
f = f.gsub(/[^[:print:]]/, '?')
|
1015
986
|
|
1016
|
-
|
1017
|
-
# if less than sz then 1 col and full width
|
1018
|
-
#
|
1019
|
-
# ix refers to the index in the complete file list, whereas we only
|
1020
|
-
# show 60 at a time
|
1021
|
-
ix = 0
|
1022
|
-
ctr = 0
|
1023
|
-
ary.each do |f|
|
1024
|
-
## ctr refers to the index in the column
|
1025
|
-
mark = SPACE
|
1026
|
-
cur = SPACE
|
1027
|
-
ind = get_shortcut(ix)
|
987
|
+
f = "#{prefix}#{f}"
|
1028
988
|
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
989
|
+
unformatted_len = f.length
|
990
|
+
if unformatted_len > wid
|
991
|
+
# take the excess out from the center on both sides
|
992
|
+
# TODO clear this up since no color info here
|
993
|
+
f = truncate_formatted_filename(f, unformatted_len, wid)
|
994
|
+
f = "#{color}#{f}#{CLEAR}" if color
|
1032
995
|
|
1033
|
-
|
1034
|
-
# cur = CURMARK if ix + @sta == @cursor # 2019-03-29 - removed reduced calls
|
1035
|
-
# NOTE seems like f and ary[ix] are the same
|
1036
|
-
mark = GMARK if selected?(ary[ix])
|
996
|
+
elsif unformatted_len < wid
|
1037
997
|
|
1038
|
-
#
|
1039
|
-
|
1040
|
-
|
998
|
+
# f << ' ' * (wid - unformatted_len)
|
999
|
+
f = "#{color}#{f}#{CLEAR}" + ' ' * (wid - unformatted_len)
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
return f
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def get_width arysz, siz
|
1006
|
+
ars = [@pagesize, arysz].min
|
1007
|
+
d = 0
|
1008
|
+
return @gcols - d if ars <= siz
|
1041
1009
|
|
1042
|
-
|
1010
|
+
tmp = (ars * 1.000 / siz).ceil
|
1011
|
+
wid = @gcols / tmp - d
|
1012
|
+
wid
|
1013
|
+
end
|
1043
1014
|
|
1044
|
-
|
1045
|
-
|
1015
|
+
def get_mark file
|
1016
|
+
return SPACE if @selected_files.empty? && @visited_files.empty?
|
1046
1017
|
|
1047
|
-
|
1048
|
-
|
1049
|
-
s = "#{color}#{s}#{CLEAR}" if color
|
1018
|
+
@current_dir ||= Dir.pwd
|
1019
|
+
fullname = File.join(@current_dir, file)
|
1050
1020
|
|
1051
|
-
|
1021
|
+
return GMARK if selected?(fullname)
|
1022
|
+
return '+' if visited? fullname
|
1052
1023
|
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
buff
|
1024
|
+
SPACE
|
1025
|
+
# cur = CURMARK if ix + @sta == @cursor # 2019-03-29 - removed reduced calls
|
1026
|
+
# NOTE seems like f and ary[ix] are the same
|
1057
1027
|
end
|
1058
1028
|
|
1059
1029
|
def format_long_listing f
|
@@ -1088,8 +1058,9 @@ def format_long_listing f
|
|
1088
1058
|
end
|
1089
1059
|
|
1090
1060
|
# determine color for a filename based on extension, then pattern, then filetype
|
1091
|
-
def color_for
|
1092
|
-
return nil if
|
1061
|
+
def color_for f
|
1062
|
+
return nil if f == SEPARATOR
|
1063
|
+
fname = f[0] == '~' ? File.expand_path(f) : f
|
1093
1064
|
|
1094
1065
|
extension = File.extname(fname)
|
1095
1066
|
color = @ls_color[extension]
|
@@ -1257,9 +1228,9 @@ def open_file f
|
|
1257
1228
|
system(comm.to_s)
|
1258
1229
|
setup_terminal
|
1259
1230
|
# XXX maybe use absolute_path instead of hardcoding
|
1260
|
-
f =
|
1231
|
+
f = @current_dir + '/' + f if f[0] != '/'
|
1261
1232
|
@visited_files.insert(0, f)
|
1262
|
-
push_used_dirs
|
1233
|
+
push_used_dirs @current_dir
|
1263
1234
|
else
|
1264
1235
|
perror "open_file: (#{f}) not found"
|
1265
1236
|
# could check home dir or CDPATH env variable DO
|
@@ -1352,6 +1323,7 @@ def change_dir f
|
|
1352
1323
|
|
1353
1324
|
f = File.expand_path(f)
|
1354
1325
|
Dir.chdir f
|
1326
|
+
@current_dir = Dir.pwd # 2019-04-24 - earlier was in post_cd but too late
|
1355
1327
|
read_directory
|
1356
1328
|
post_cd
|
1357
1329
|
|
@@ -1574,7 +1546,7 @@ def print_help
|
|
1574
1546
|
ary = columnate ary, (ary.size / 2) + 1
|
1575
1547
|
ary.each { |line| file.puts line }
|
1576
1548
|
end
|
1577
|
-
end
|
1549
|
+
end # print_help
|
1578
1550
|
|
1579
1551
|
def page_stat_for_file
|
1580
1552
|
stat = `stat #{current_file}`
|
@@ -1591,8 +1563,12 @@ def page_flags
|
|
1591
1563
|
page_with_tempfile do |file|
|
1592
1564
|
file.puts 'Values of toggles/flags'
|
1593
1565
|
file.puts '-----------------------'
|
1594
|
-
@toggles.
|
1595
|
-
|
1566
|
+
@toggles.each_pair do |flag, v|
|
1567
|
+
if instance_variable_defined? "@#{flag}"
|
1568
|
+
value = instance_variable_get "@#{flag}"
|
1569
|
+
else
|
1570
|
+
value = v
|
1571
|
+
end
|
1596
1572
|
file.puts "#{flag} : #{value}"
|
1597
1573
|
end
|
1598
1574
|
file.puts '-----------------------'
|
@@ -1693,6 +1669,7 @@ def bookmark_menu
|
|
1693
1669
|
h = {
|
1694
1670
|
v: :view_bookmarks,
|
1695
1671
|
c: :create_bookmark,
|
1672
|
+
r: :remove_bookmark,
|
1696
1673
|
g: :goto_bookmark
|
1697
1674
|
}
|
1698
1675
|
menu 'Bookmark Menu', h
|
@@ -1752,7 +1729,8 @@ def toggle_menu
|
|
1752
1729
|
v: :visual_mode,
|
1753
1730
|
t: :truncate_from,
|
1754
1731
|
n: :enhanced_mode,
|
1755
|
-
i: :instant_search
|
1732
|
+
i: :instant_search,
|
1733
|
+
H: :highlight_row_flag }
|
1756
1734
|
# TODO: add other values at end, what key ?
|
1757
1735
|
|
1758
1736
|
_, menu_text = menu 'Toggle Menu', h
|
@@ -2100,7 +2078,6 @@ def post_cd
|
|
2100
2078
|
@title = @patt = @message = nil
|
2101
2079
|
@sta = @cursor = @stact = 0
|
2102
2080
|
@visual_block_start = nil
|
2103
|
-
@current_dir = Dir.pwd
|
2104
2081
|
screen_settings
|
2105
2082
|
|
2106
2083
|
# goto last position cursor was in this dir
|
@@ -2169,7 +2146,6 @@ def create_bookmark
|
|
2169
2146
|
key = get_char
|
2170
2147
|
# print "\e[?25l" # hide cursor
|
2171
2148
|
if /^[0-9A-Za-z]$/.match?(key)
|
2172
|
-
# @bookmarks[key] = "#{Dir.pwd}:#{@cursor}"
|
2173
2149
|
set_bookmark key
|
2174
2150
|
@modified = true
|
2175
2151
|
message "Created bookmark #{key} for #{File.basename(Dir.pwd)}."
|
@@ -2178,6 +2154,20 @@ def create_bookmark
|
|
2178
2154
|
end
|
2179
2155
|
end
|
2180
2156
|
|
2157
|
+
def remove_bookmark
|
2158
|
+
bmlist = @bookmarks.keys.sort.join('')
|
2159
|
+
clear_last_line
|
2160
|
+
print "Enter bookmark to delete: #{bmlist}:"
|
2161
|
+
key = get_char
|
2162
|
+
if bmlist.index(key)
|
2163
|
+
@modified = true
|
2164
|
+
@bookmarks.delete key
|
2165
|
+
message "Deleted #{key} "
|
2166
|
+
else
|
2167
|
+
perror 'Bookmark does not exist'
|
2168
|
+
end
|
2169
|
+
end
|
2170
|
+
|
2181
2171
|
# allow user to exit using :q :wq :x
|
2182
2172
|
# Was this supposed to be augmented, or just remain limited like this
|
2183
2173
|
# We should be able to do everything in the menus from here. TODO
|
@@ -3024,25 +3014,27 @@ end
|
|
3024
3014
|
## scroll cursor down
|
3025
3015
|
def cursor_scroll_dn
|
3026
3016
|
@cursor_movement = :down
|
3027
|
-
|
3017
|
+
@old_cursor = @cursor
|
3018
|
+
move_to(pos + MSCROLL)
|
3028
3019
|
end
|
3029
3020
|
|
3030
3021
|
def cursor_scroll_up
|
3031
3022
|
@cursor_movement = :up
|
3032
|
-
|
3023
|
+
@old_cursor = @cursor
|
3024
|
+
move_to(pos - MSCROLL)
|
3033
3025
|
end
|
3034
3026
|
|
3035
3027
|
# move cursor down a line
|
3036
3028
|
def cursor_dn
|
3037
3029
|
@cursor_movement = :down
|
3038
3030
|
@old_cursor = @cursor
|
3039
|
-
|
3031
|
+
move_to(pos + 1)
|
3040
3032
|
end
|
3041
3033
|
|
3042
3034
|
def cursor_up
|
3043
3035
|
@old_cursor = @cursor
|
3044
3036
|
@cursor_movement = :up
|
3045
|
-
|
3037
|
+
move_to(pos - 1)
|
3046
3038
|
end
|
3047
3039
|
|
3048
3040
|
# return cursor position
|
@@ -3051,8 +3043,9 @@ def pos
|
|
3051
3043
|
end
|
3052
3044
|
|
3053
3045
|
# move cursor to given position/line
|
3054
|
-
def
|
3046
|
+
def move_to position
|
3055
3047
|
orig = @cursor
|
3048
|
+
place_cursor(CLEAR) if @highlight_row_flag
|
3056
3049
|
@cursor = position
|
3057
3050
|
@cursor = [@cursor, @view.size - 1].min
|
3058
3051
|
@cursor = [@cursor, 0].max
|
@@ -3081,10 +3074,11 @@ def moveto position
|
|
3081
3074
|
|
3082
3075
|
@cursor_movement = nil if oldsta != @sta # we need to redraw
|
3083
3076
|
|
3084
|
-
|
3085
|
-
fin = [orig, @cursor].max
|
3077
|
+
# -------- return here --- only visual mode continues ---------------------#
|
3086
3078
|
return unless @visual_mode
|
3087
3079
|
|
3080
|
+
star = [orig, @cursor].min
|
3081
|
+
fin = [orig, @cursor].max
|
3088
3082
|
@cursor_movement = nil # visual mode needs to redraw page
|
3089
3083
|
|
3090
3084
|
# PWD has to be there in selction
|
@@ -3103,19 +3097,15 @@ end
|
|
3103
3097
|
# --
|
3104
3098
|
|
3105
3099
|
# is given file in selected array
|
3106
|
-
def visited?
|
3107
|
-
@
|
3108
|
-
file = File.join(@current_dir, file)
|
3109
|
-
return @visited_files.index file
|
3100
|
+
def visited? fullname
|
3101
|
+
return @visited_files.index fullname
|
3110
3102
|
end
|
3111
3103
|
|
3112
3104
|
# ------------- selection related methods --------------------------------#
|
3113
3105
|
|
3114
3106
|
# is given file in selected array
|
3115
|
-
def selected?
|
3116
|
-
@
|
3117
|
-
file = File.join(@current_dir, file)
|
3118
|
-
return @selected_files.index file
|
3107
|
+
def selected? fullname
|
3108
|
+
return @selected_files.index fullname
|
3119
3109
|
end
|
3120
3110
|
|
3121
3111
|
# add given file/s to selected file list
|
@@ -3226,6 +3216,8 @@ def filetype f
|
|
3226
3216
|
return :zip if s.index(/[Zz]ip/)
|
3227
3217
|
return :zip if s.index('archive')
|
3228
3218
|
return :image if s.index 'image'
|
3219
|
+
return :sqlite if s.index 'SQLite'
|
3220
|
+
# return :db if s.index 'database'
|
3229
3221
|
return :text if s.index 'data'
|
3230
3222
|
|
3231
3223
|
nil
|
@@ -3238,9 +3230,11 @@ def opener_for f
|
|
3238
3230
|
# Get filetype, and check for command for type, else extn else unknown
|
3239
3231
|
if !@editor_mode
|
3240
3232
|
ft = filetype f
|
3233
|
+
@log.debug "opener: #{ft} for #{f}"
|
3241
3234
|
comm = PAGER_COMMAND[ft] if ft
|
3242
3235
|
comm ||= PAGER_COMMAND[File.extname(f)]
|
3243
3236
|
comm ||= PAGER_COMMAND[:unknown]
|
3237
|
+
@log.debug "opener: #{comm}"
|
3244
3238
|
else
|
3245
3239
|
# 2019-04-10 - what does this mean, that in editor_mode, editor
|
3246
3240
|
# opens everything? what of images etc
|
@@ -3490,6 +3484,7 @@ end
|
|
3490
3484
|
def enhance_file_list
|
3491
3485
|
# return unless cget(:enhanced_mode)
|
3492
3486
|
return unless @enhanced_mode
|
3487
|
+
@current_dir ||= Dir.pwd
|
3493
3488
|
|
3494
3489
|
begin
|
3495
3490
|
actr = @files.size
|
@@ -3523,7 +3518,7 @@ def enhance_file_list
|
|
3523
3518
|
if @files.index('Gemfile') || !@files.grep(/\.gemspec/).empty?
|
3524
3519
|
# usually the lib dir has only one file and one dir
|
3525
3520
|
flg = false
|
3526
|
-
@files.concat get_important_files(
|
3521
|
+
@files.concat get_important_files(@current_dir)
|
3527
3522
|
if @files.index('lib/')
|
3528
3523
|
# get first five entries by modification time
|
3529
3524
|
# f1 = `zsh -c 'print -rl -- lib/*(om[1,5]MN)'`.split("\n")
|
@@ -3535,7 +3530,7 @@ def enhance_file_list
|
|
3535
3530
|
end
|
3536
3531
|
|
3537
3532
|
# look into lib file for that project
|
3538
|
-
dd = File.basename(
|
3533
|
+
dd = File.basename(@current_dir)
|
3539
3534
|
if f.index("lib/#{dd}/")
|
3540
3535
|
# f1 = `zsh -c 'print -rl -- lib/#{dd}/*(om[1,5]MN)'`.split("\n")
|
3541
3536
|
f = get_files_by_mtime("lib/#{dd}")&.first(5)
|
@@ -3747,20 +3742,13 @@ def print_on_right text
|
|
3747
3742
|
col = @gcols - sz - 1
|
3748
3743
|
col = 2 if col < 2
|
3749
3744
|
text = text[0..@gcols - 3] if sz > @gcols - 2
|
3750
|
-
#
|
3751
|
-
system "tput cup #{@glines} #{col}"
|
3752
|
-
|
3745
|
+
# 2019-04-22 - earlier direct system call to tput, now trying print
|
3746
|
+
# system "tput cup #{@glines} #{col}"
|
3747
|
+
tput_cup @glines, @gcols - sz - 1
|
3753
3748
|
# print text
|
3754
3749
|
print "\e[33;4#{@status_color_right}m#{text}\e[m"
|
3755
3750
|
end
|
3756
3751
|
|
3757
|
-
# unused, should set bgcolor before printing
|
3758
|
-
def print_last_line text
|
3759
|
-
# unused ??
|
3760
|
-
last_line
|
3761
|
-
print text
|
3762
|
-
end
|
3763
|
-
|
3764
3752
|
def clear_message
|
3765
3753
|
if @keys_to_clear
|
3766
3754
|
@keys_to_clear -= 1
|
@@ -3777,8 +3765,8 @@ def only_cursor_moved?
|
|
3777
3765
|
return unless @cursor_movement && @old_cursor
|
3778
3766
|
|
3779
3767
|
# if cursor has not moved (first or last item on screen)
|
3780
|
-
# keep testing this out 2019-04-14 -
|
3781
3768
|
if @old_cursor == @cursor
|
3769
|
+
place_cursor # otherwise highlight vanishes if keep pressing UP on first row.
|
3782
3770
|
@cursor_movement = false
|
3783
3771
|
return true # next in the loop
|
3784
3772
|
end
|
data/cetus.gemspec
CHANGED
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'cetus'
|
9
|
-
spec.version = '0.
|
9
|
+
spec.version = '0.2.0'
|
10
10
|
spec.authors = ['Rahul Kumar']
|
11
11
|
spec.email = ['oneness.univ@gmail.com']
|
12
12
|
spec.description = %q{lightning fast file navigator}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cetus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahul Kumar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|