cetus 0.1.27 → 0.1.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +50 -5
- data/bin/cetus +138 -159
- 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: 021f5de97b41df8fb3438258356b924b9101033088180d6315579083793eae4a
|
4
|
+
data.tar.gz: a1d07c2f93633c2655a004b67dfbcdcc45429135cc7e6d2adc84d514a0331fb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9fff90c5dc1e629e196dfafb880168450878ade3871093ddb908b5deaf3fb72d600f9766be3148318a1bbed35b8b80783ea621738dcb0f5ecf82180504f68bb
|
7
|
+
data.tar.gz: 4d53ac51c02fa54f5f002db9c54fd8083f406d7c498a66910f8095084880b2d284f1c3f1078aeba5e893dc831eb22d33cf13a4af5b9e2b9a2c62bf4697de0a7c
|
data/README.md
CHANGED
@@ -8,7 +8,8 @@ Tested with ruby 2.5
|
|
8
8
|
Latest changes:
|
9
9
|
2019-03-04 - q is quit key, not Q
|
10
10
|
- show directories first, then files.
|
11
|
-
- trying not to pollute main screen with listings.
|
11
|
+
- trying not to pollute main screen/terminal with listings (i.e. use alt screen)
|
12
|
+
- C-s to select (toggle) current file
|
12
13
|
|
13
14
|
2018-03-12 - now using LEFT and RIGHT arrow keys to go down into a directory, or up to higher directory.
|
14
15
|
Also, pressing RIGHT ARROW on a file with open the file.
|
@@ -16,6 +17,50 @@ Previously RIGHT and LEFT arrows would move to next or previous columns, i have
|
|
16
17
|
|
17
18
|
2018-03-13 - unable to push new gem 0.1.16 to rubygems.
|
18
19
|
|
20
|
+
|
21
|
+
## Selecting a file
|
22
|
+
|
23
|
+
There are two ways of selecting a file.
|
24
|
+
|
25
|
+
1. Pressing C-s on a file.
|
26
|
+
2. Use hotkey (on left of file) to select without having to navigate.
|
27
|
+
|
28
|
+
While using C-s marks a file as selected, pressing the hotkey will either open
|
29
|
+
the file using PAGER or EDITOR depending on current mode.
|
30
|
+
|
31
|
+
## Multiple Selection of files
|
32
|
+
|
33
|
+
1. Press C-s on multiple files.
|
34
|
+
2. Press `@` to enter multiple select mode.
|
35
|
+
Now press the hotkey (left of file) to select it.
|
36
|
+
|
37
|
+
To execute an action on multiple (or single) files, you may press `C-x` and choose
|
38
|
+
an action such as move or delete, etc.
|
39
|
+
|
40
|
+
You may also select all files with the same extension as current file. Invoke the
|
41
|
+
filter menu using Tilde-F. Now select `x` or `:extension`.
|
42
|
+
|
43
|
+
`Tilde-y` is the selection menu. M-a is select all, M-A is unselect all.
|
44
|
+
|
45
|
+
## Moving multiple files
|
46
|
+
|
47
|
+
First select multiple files by the above means.
|
48
|
+
|
49
|
+
Now there are two ways to move selected files to another directory.
|
50
|
+
|
51
|
+
1. Press `C-x m` and type the name of the directory at the prompt.
|
52
|
+
|
53
|
+
2. Navigate to the target directory, and then press `C-x m` and type "." at the prompt.
|
54
|
+
|
55
|
+
## Copying files to another directory.
|
56
|
+
|
57
|
+
Use the same procedure as for moving files but press `C-x c`
|
58
|
+
|
59
|
+
1. Press `C-x c` and then type the name of the target directory at the prompt.
|
60
|
+
|
61
|
+
2. Navigate to the target directory, and press `C-x c`, and type '.' at the prompt.
|
62
|
+
|
63
|
+
|
19
64
|
fork of lyra with a different hotkey idea. Use this for quickly navigating your file system using hotkeys
|
20
65
|
and bookmarks, and executing commands on single or multiple files easily.
|
21
66
|
|
@@ -48,7 +93,7 @@ The rest is similar to lyra. Some key points are highlighted here.
|
|
48
93
|
|
49
94
|
* Single-quote and small letter jumps to the first file starting with given letter. e.g. `'s`
|
50
95
|
|
51
|
-
* Space
|
96
|
+
* Space-bar pages, also Alt n and p. Ctrl-d and Ctrl-b goes down 10 rows.
|
52
97
|
|
53
98
|
* 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.
|
54
99
|
|
@@ -56,7 +101,7 @@ Other than using bookmarks, you can jump quickly to other directories or open fi
|
|
56
101
|
|
57
102
|
* 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.
|
58
103
|
|
59
|
-
* By default selecting a file invokes $EDITOR, the default command can be changed from the menu.
|
104
|
+
* By default selecting a file invokes $EDITOR, the default command can be changed from the menu. While on a file, pressing C-e opens in EDITOR, and C-p opens in PAGER.
|
60
105
|
|
61
106
|
* Switch between editor mode and page mode. OFten you wish to quickly view files (maybe for deleting or moving). You don't want these files to get listed in .viminfo. Switching to pager mode, invokes your $MANPAGER on selected files which makes navigation faster. Set `most` to your MANPAGER.
|
62
107
|
|
@@ -66,7 +111,7 @@ Other than using bookmarks, you can jump quickly to other directories or open fi
|
|
66
111
|
|
67
112
|
* Use slash "/" to run a regex on the dir listing.
|
68
113
|
|
69
|
-
* Use question "?"
|
114
|
+
* Use question "?" to view help (was directory tree earlier)
|
70
115
|
|
71
116
|
* Use ESCAPE or C-c to clear any filter, regex, sort order, sub-listing etc
|
72
117
|
|
@@ -91,7 +136,7 @@ Thus, F2 gives only child dirs in current dir, F3 gives recursive directories an
|
|
91
136
|
|
92
137
|
## Requirements ##
|
93
138
|
|
94
|
-
Requires ruby 1.9.3, and uses zsh for globbing.
|
139
|
+
Requires ruby 1.9.3 or higher, and uses zsh for globbing.
|
95
140
|
Uses $EDITOR and $MANPAGER or $PAGER.
|
96
141
|
|
97
142
|
Optionally uses ack, locate, find for options with that name. You may replace ack with ag or other.
|
data/bin/cetus
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# Author: rkumar http://github.com/rkumar/cetus/
|
7
7
|
# Date: 2013-02-17 - 17:48
|
8
8
|
# License: GPL
|
9
|
-
# Last update: 2019-03-
|
9
|
+
# Last update: 2019-03-22 00:12
|
10
10
|
# --------------------------------------------------------------------------- #
|
11
11
|
# cetus.rb Copyright (C) 2012-2019 rahul kumar
|
12
12
|
# == CHANGELOG
|
@@ -26,7 +26,6 @@ require 'io/wait'
|
|
26
26
|
require 'shellwords'
|
27
27
|
# https://docs.ruby-lang.org/en/2.6.0/FileUtils.html
|
28
28
|
require 'fileutils'
|
29
|
-
# -- requires 1.9.3 for io/wait
|
30
29
|
|
31
30
|
## INSTALLATION
|
32
31
|
# copy into PATH
|
@@ -35,7 +34,7 @@ require 'fileutils'
|
|
35
34
|
|
36
35
|
# 2019-02-20 - added so alt-screen is used
|
37
36
|
system 'tput smcup'
|
38
|
-
VERSION = '0.1.
|
37
|
+
VERSION = '0.1.28.0'.freeze
|
39
38
|
CONFIG_FILE = '~/.config/cetus/conf.yml'.freeze
|
40
39
|
|
41
40
|
$bindings = {}
|
@@ -57,17 +56,17 @@ $bindings = {
|
|
57
56
|
'!' => 'execute',
|
58
57
|
',' => 'goto_parent_dir',
|
59
58
|
'~' => 'goto_home_dir',
|
60
|
-
'-' => 'goto_previous_dir',
|
61
|
-
'+' => 'goto_dir',
|
59
|
+
'-' => 'goto_previous_dir',
|
60
|
+
'+' => 'goto_dir', # 2019-03-07 - TODO: change binding
|
62
61
|
'.' => 'pop_dir',
|
63
62
|
':' => 'subcommand',
|
64
63
|
"'" => 'goto_bookmark',
|
65
64
|
'/' => 'enter_regex',
|
66
65
|
'M-p' => 'prev_page',
|
67
66
|
'M-n' => 'next_page',
|
68
|
-
'SPACE' => 'next_page',
|
69
|
-
'M-f' => '
|
70
|
-
'M-d' => '
|
67
|
+
'SPACE' => 'next_page:Page Down',
|
68
|
+
'M-f' => 'select_from_visited_files',
|
69
|
+
'M-d' => 'select_from_used_dirs',
|
71
70
|
'M-b' => 'bookmark_menu',
|
72
71
|
'M-m' => 'create_bookmark',
|
73
72
|
'M-M' => 'view_bookmarks',
|
@@ -82,11 +81,11 @@ $bindings = {
|
|
82
81
|
# "RIGHT" => "column_next",
|
83
82
|
'RIGHT' => 'select_current', # changed 2018-03-12 - for faster navigation
|
84
83
|
'LEFT' => 'goto_parent_dir', # changed on 2018-03-12 - earlier column_next 1
|
85
|
-
']' => 'column_next',
|
86
|
-
'[' => 'column_next 1',
|
84
|
+
']' => 'column_next: goto next column',
|
85
|
+
'[' => 'column_next 1: goto previous column',
|
87
86
|
'C-x' => 'file_actions',
|
88
|
-
'M--' => 'columns_incdec -1',
|
89
|
-
'M-+' => 'columns_incdec 1',
|
87
|
+
'M--' => 'columns_incdec -1: reduce column width',
|
88
|
+
'M-+' => 'columns_incdec 1: increase column width',
|
90
89
|
'S' => 'command_file list y ls -lh',
|
91
90
|
'L' => 'command_file Page n less',
|
92
91
|
'C-d' => 'cursor_scroll_dn',
|
@@ -152,14 +151,6 @@ $kh[KEY_F10] = 'F10'
|
|
152
151
|
$kh[KEY_S_F1] = 'S-F1'
|
153
152
|
$kh['[1;2Q'] = 'S-F2'
|
154
153
|
|
155
|
-
def old_clear_screen
|
156
|
-
system 'clear'
|
157
|
-
return
|
158
|
-
system('tput cup 0 0')
|
159
|
-
# system 'tput ed'
|
160
|
-
print "\e[J"
|
161
|
-
end
|
162
|
-
|
163
154
|
# copied from fff
|
164
155
|
def clear_screen
|
165
156
|
# Only clear the scrolling window (dir item list).
|
@@ -207,11 +198,16 @@ def setup_terminal
|
|
207
198
|
end
|
208
199
|
|
209
200
|
# wrap readline so C-c can be ignored, but blank is taken as default
|
210
|
-
def readline
|
201
|
+
def readline prompt='>'
|
202
|
+
# unhide cursor
|
203
|
+
print "\e[?25h"
|
211
204
|
begin
|
212
|
-
target = Readline.readline(
|
205
|
+
target = Readline.readline(prompt, true)
|
213
206
|
rescue Interrupt
|
214
207
|
return nil
|
208
|
+
ensure
|
209
|
+
# hide cursor
|
210
|
+
print "\e[?25l"
|
215
211
|
end
|
216
212
|
target
|
217
213
|
end
|
@@ -219,7 +215,7 @@ end
|
|
219
215
|
## get a character from user and return as a string
|
220
216
|
# Adapted from:
|
221
217
|
# http://stackoverflow.com/questions/174933/how-to-get-a-single-character-without-pressing-enter/8274275#8274275
|
222
|
-
# Need to take complex keys and
|
218
|
+
# Need to take complex keys and match against a hash.
|
223
219
|
def get_char
|
224
220
|
system('stty raw -echo 2>/dev/null') # turn raw input on
|
225
221
|
c = nil
|
@@ -262,13 +258,10 @@ def get_char
|
|
262
258
|
# end
|
263
259
|
return c.chr if c
|
264
260
|
ensure
|
265
|
-
# system "stty -raw echo" # turn raw input off
|
266
261
|
system('stty -raw echo 2>/dev/null') # turn raw input on
|
267
262
|
end
|
268
263
|
|
269
264
|
## GLOBALS
|
270
|
-
# $IDX="123456789abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
271
|
-
# $IDX="abcdefghijklmnopqrstuvwxy"
|
272
265
|
$IDX = ('a'..'y').to_a
|
273
266
|
$IDX.delete 'q'
|
274
267
|
$IDX.concat ('za'..'zz').to_a
|
@@ -296,7 +289,8 @@ $pager_command = {
|
|
296
289
|
unknown: 'open'
|
297
290
|
}
|
298
291
|
$dir_position = {}
|
299
|
-
|
292
|
+
|
293
|
+
## ----------------- CONSTANTS ----------------- ##
|
300
294
|
GMARK = '*'.freeze
|
301
295
|
CURMARK = '>'.freeze
|
302
296
|
MSCROLL = 10
|
@@ -314,6 +308,8 @@ ON_BLUE = "\e[44m".freeze
|
|
314
308
|
REVERSE = "\e[7m".freeze
|
315
309
|
UNDERLINE = "\e[4m".freeze
|
316
310
|
CURSOR_COLOR = ON_BLUE
|
311
|
+
## --------------------------------------------- ##
|
312
|
+
|
317
313
|
$patt = nil
|
318
314
|
$ignorecase = true
|
319
315
|
$quitting = false
|
@@ -331,10 +327,9 @@ $history = []
|
|
331
327
|
$sta = $cursor = 0
|
332
328
|
$visual_mode = false
|
333
329
|
$status_color = 4 # status line, can be 2 3 4 5 6
|
334
|
-
# $help = "#{BOLD}1-9a-zA-Z#{BOLD_OFF} Select #{BOLD}/#{BOLD_OFF} Grep #{BOLD}'#{BOLD_OFF} First char #{BOLD}M-n/p#{BOLD_OFF} Paging #{BOLD}!#{BOLD_OFF} Execute #{BOLD}@#{BOLD_OFF} Selection Mode #{BOLD}q#{BOLD_OFF} Quit"
|
335
330
|
|
336
331
|
# Menubar on top of screen
|
337
|
-
|
332
|
+
@help = "#{BOLD}?#{BOLD_OFF} Help #{BOLD}`#{BOLD_OFF} Menu #{BOLD}!#{BOLD_OFF} Execute #{BOLD}=#{BOLD_OFF} Toggle #{BOLD}C-x#{BOLD_OFF} File Actions #{BOLD}q#{BOLD_OFF} Quit "
|
338
333
|
|
339
334
|
## main loop which calls all other programs
|
340
335
|
def run
|
@@ -349,11 +344,13 @@ def run
|
|
349
344
|
|
350
345
|
fl = $files.size
|
351
346
|
|
352
|
-
# selectedix = nil
|
353
|
-
# $patt = ''
|
354
347
|
$patt = nil
|
355
348
|
$sta = 0
|
349
|
+
|
350
|
+
# forever loop that prints dir and takes a key
|
356
351
|
loop do
|
352
|
+
|
353
|
+
# view consists of all files (filtered by pattern if necessary)
|
357
354
|
$view = if $patt
|
358
355
|
if $ignorecase
|
359
356
|
$files.grep(/#{$patt}/i)
|
@@ -363,17 +360,21 @@ def run
|
|
363
360
|
else
|
364
361
|
$files
|
365
362
|
end
|
363
|
+
|
366
364
|
fl = $view.size
|
367
365
|
$sta = 0 if $sta >= fl || $sta < 0
|
368
366
|
# 2019-03-18 - added to ensure cursor not going OOB when next_page
|
369
367
|
$cursor = 0 if $cursor >= fl || $cursor < 0
|
368
|
+
|
370
369
|
# NOTE if we make cursor zero, then it can be < sta so in the next line
|
371
370
|
# it will be made equal to sta which we may not want
|
372
371
|
# $sta = $cursor if $sta > $cursor
|
373
372
|
$cursor = $sta if $sta > $cursor
|
374
373
|
|
374
|
+
# viewport are the files that are visible, subset of view
|
375
375
|
$viewport = $view[$sta, $pagesize]
|
376
376
|
fin = $sta + $viewport.size
|
377
|
+
|
377
378
|
# added 2019-03-20 - actually stact should be reduced not brought to zero
|
378
379
|
# 2019-03-21 - NOTE this may be redundant since I set to zero in next_page
|
379
380
|
# due to various edge cases.
|
@@ -382,20 +383,18 @@ def run
|
|
382
383
|
$stact -= $grows while $stact >= $viewport.size
|
383
384
|
$stact += $grows if $stact < 0
|
384
385
|
end
|
386
|
+
|
385
387
|
$title ||= Dir.pwd.sub(home, '~')
|
386
388
|
clear_screen
|
387
389
|
|
388
390
|
|
389
391
|
# title
|
390
|
-
print "#{GREEN}#{
|
392
|
+
print "#{GREEN}#{@help} #{BLUE}cetus #{VERSION}#{CLEAR}\n"
|
391
393
|
t = "#{$title} #{$sta + 1} to #{fin} of #{fl} #{$sorto} F:#{$filterstr}"
|
392
394
|
t = t[t.size - $gcols..-1] if t.size >= $gcols
|
393
395
|
print "#{BOLD}#{t}#{CLEAR}\n"
|
394
396
|
|
395
|
-
|
396
|
-
## nilling the title means a superimposed one gets cleared.
|
397
|
-
# $title = nil
|
398
|
-
# split into 2 procedures so columnate can e clean and reused.
|
397
|
+
# add hint and format the line
|
399
398
|
buff = _format $viewport
|
400
399
|
|
401
400
|
# break into as many columns as required
|
@@ -407,24 +406,27 @@ def run
|
|
407
406
|
print
|
408
407
|
|
409
408
|
# prompt
|
410
|
-
|
411
|
-
v_mm = ''
|
412
|
-
v_mm = "[#{$mode}] " if $mode
|
409
|
+
v_mm = $mode ? "[#{$mode}] " : ''
|
413
410
|
cf = current_file
|
414
411
|
$message = "No file highlighted (#{cf})" if cf and !$highlighted_a_column
|
415
412
|
$message = ' | No matches. Press ESCAPE' if $patt && !cf
|
416
413
|
# 2019-03-19 - take cursor to last line
|
417
414
|
system "tput cup #{$glines} 0"
|
418
|
-
|
415
|
+
|
416
|
+
# print a colored line at bottom of screen
|
417
|
+
# \e[33;41m - set color of status_line
|
418
|
+
# %*s - set blank spaces for entire line
|
419
419
|
print "\e[33;4%sm%*s" % [$status_color || '1', $gcols, " "]
|
420
420
|
|
421
|
+
# Print the filename at the right side of the status_line
|
421
422
|
# sometimes due to search, there is no file
|
422
423
|
if cf
|
423
424
|
cfl = cf.size
|
424
|
-
# print right
|
425
|
-
|
425
|
+
# print right aligned
|
426
|
+
padding = @debug_flag ? 15 : 3
|
427
|
+
system "tput cup #{$glines} #{$gcols - cfl - padding}"
|
426
428
|
# print "#{REVERSE}#{cf}#{CLEAR}"
|
427
|
-
if
|
429
|
+
if @debug_flag
|
428
430
|
print "#{$sta},#{$cursor},#{$stact},#{$viewport.size},#{$grows} | #{cf}"
|
429
431
|
else
|
430
432
|
print "#{cf}"
|
@@ -440,7 +442,7 @@ def run
|
|
440
442
|
# elsif ch =~ /^[1-9a-zA-Z]$/
|
441
443
|
# 2019-03-04 - ignore q since that is quit key now
|
442
444
|
# if ch =~ /^[a-zZ]$/
|
443
|
-
if ch
|
445
|
+
if ch.match?(/^[a-pr-zZ]$/)
|
444
446
|
# hint mode
|
445
447
|
select_hint $viewport, ch
|
446
448
|
ctr = 0
|
@@ -449,8 +451,11 @@ def run
|
|
449
451
|
$message = $patt = nil if $patt == ''
|
450
452
|
ctr = 0
|
451
453
|
else
|
452
|
-
# binding
|
454
|
+
# fetch binding for key
|
453
455
|
x = $bindings[ch]
|
456
|
+
# remove comment string so only binding is left
|
457
|
+
x, _ = x.split(':') if x
|
458
|
+
# split into binding and args
|
454
459
|
x = x.split if x
|
455
460
|
if x
|
456
461
|
binding = x.shift
|
@@ -630,7 +635,7 @@ def _format(ary)
|
|
630
635
|
stat ||= File.stat(File.expand_path(f))
|
631
636
|
f = format('%10s %s %s', readable_file_size(stat.size, 1),
|
632
637
|
date_format(stat.mtime), f)
|
633
|
-
rescue
|
638
|
+
rescue StandardError => e
|
634
639
|
f = format('%10s %s %s', '?', '??????????', f)
|
635
640
|
end
|
636
641
|
end
|
@@ -782,22 +787,20 @@ def run_command(f)
|
|
782
787
|
print "Run a command on #{files}: "
|
783
788
|
begin
|
784
789
|
# Readline::HISTORY.push(*values)
|
785
|
-
command =
|
790
|
+
command = readline
|
786
791
|
# command = gets().chomp
|
787
792
|
return if command.empty?
|
788
793
|
|
789
794
|
print 'Second part of command: '
|
790
795
|
# command2 = gets().chomp
|
791
|
-
command2 =
|
796
|
+
command2 = readline
|
792
797
|
puts "#{command} #{files} #{command2}"
|
793
798
|
system "#{command} #{files} #{command2}"
|
794
|
-
|
799
|
+
setup_terminal
|
800
|
+
rescue StandardError => ex
|
795
801
|
perror "Canceled command, (#{ex}) press a key"
|
796
802
|
return
|
797
803
|
end
|
798
|
-
begin
|
799
|
-
rescue Exception => ex
|
800
|
-
end
|
801
804
|
|
802
805
|
refresh
|
803
806
|
puts 'Press a key ...'
|
@@ -876,15 +879,18 @@ end
|
|
876
879
|
|
877
880
|
## accept dir to goto and change to that ( can be a file too)
|
878
881
|
def goto_dir
|
882
|
+
print "\e[?25h"
|
879
883
|
print 'Enter path: '
|
880
884
|
begin
|
881
885
|
# path = gets.chomp
|
882
|
-
path =
|
886
|
+
path = readline
|
883
887
|
return if path == ''
|
884
888
|
# rescue => ex
|
885
|
-
rescue
|
889
|
+
rescue StandardError => ex
|
886
890
|
perror 'Cancelled cd, press a key'
|
887
891
|
return
|
892
|
+
ensure
|
893
|
+
print "\e[?25l"
|
888
894
|
end
|
889
895
|
f = File.expand_path(path)
|
890
896
|
unless File.directory? f
|
@@ -994,7 +1000,7 @@ def enter_regex
|
|
994
1000
|
# print 'Enter (regex) pattern: '
|
995
1001
|
# move to beginning of line, and clear till EOL
|
996
1002
|
print "\r\e[K"
|
997
|
-
$patt =
|
1003
|
+
$patt = readline '/'
|
998
1004
|
end
|
999
1005
|
|
1000
1006
|
# page/scroll down.
|
@@ -1020,34 +1026,6 @@ def prev_page
|
|
1020
1026
|
$cursor -= $pagesize
|
1021
1027
|
end
|
1022
1028
|
|
1023
|
-
# print help on key-bindings
|
1024
|
-
# 2019-03-08 - write to temp file and user PAGER
|
1025
|
-
def old_print_help
|
1026
|
-
require 'tempfile'
|
1027
|
-
file = Tempfile.new('help')
|
1028
|
-
begin
|
1029
|
-
file.puts ' HELP'
|
1030
|
-
|
1031
|
-
file.puts
|
1032
|
-
file.puts 'To open a file or dir press 1-9 a-z A-Z (on left of file)'
|
1033
|
-
file.puts 'Ctrl-s to select file under cursor'
|
1034
|
-
file.puts 'Selection Mode: Each selection adds to selection list (toggles)'
|
1035
|
-
file.puts ' Execute commands on selected files. e.g D C-x '
|
1036
|
-
file.puts ' Upon exiting mode, selection is cleared'
|
1037
|
-
file.puts 'Use left and right arrows to move through directories'
|
1038
|
-
file.puts
|
1039
|
-
ary = []
|
1040
|
-
$bindings.each_pair { |k, v| ary.push "#{k.ljust(7)} => #{v}" }
|
1041
|
-
ary = columnate ary, (ary.size/2)+1
|
1042
|
-
ary.each { |line| file.puts line }
|
1043
|
-
file.flush
|
1044
|
-
system "$PAGER #{file.path}"
|
1045
|
-
rescue
|
1046
|
-
file.close
|
1047
|
-
file.unlink
|
1048
|
-
end
|
1049
|
-
end
|
1050
|
-
|
1051
1029
|
def print_help
|
1052
1030
|
page_with_tempfile do |file|
|
1053
1031
|
file.puts ' HELP'
|
@@ -1061,9 +1039,12 @@ def print_help
|
|
1061
1039
|
file.puts 'Use left and right arrows to move through directories'
|
1062
1040
|
file.puts
|
1063
1041
|
ary = []
|
1064
|
-
#
|
1065
|
-
|
1066
|
-
|
1042
|
+
# 2019-03-19 - if : then show text after colon
|
1043
|
+
$bindings.each_pair { |k, v|
|
1044
|
+
vv = v.tr('_', ' ')
|
1045
|
+
vv = vv.split(':')[1].strip if vv.include?(':')
|
1046
|
+
ary.push "#{k.ljust(7)} => #{vv}"
|
1047
|
+
}
|
1067
1048
|
# FIXME this works but not properly when long_listing is true.
|
1068
1049
|
# We should avoid using columnate as there are several file related things.
|
1069
1050
|
ary = columnate ary, (ary.size/2)+1
|
@@ -1088,14 +1069,15 @@ def page_with_tempfile
|
|
1088
1069
|
yield file
|
1089
1070
|
file.flush
|
1090
1071
|
system "$PAGER #{file.path}"
|
1091
|
-
|
1072
|
+
setup_terminal
|
1073
|
+
rescue StandardError
|
1092
1074
|
file.close
|
1093
1075
|
file.unlink
|
1094
1076
|
end
|
1095
1077
|
end
|
1096
1078
|
|
1097
1079
|
def debug_vars
|
1098
|
-
|
1080
|
+
@debug_flag = true
|
1099
1081
|
page_with_tempfile do |file|
|
1100
1082
|
file.puts 'DEBUG VARIABLES ARE:'
|
1101
1083
|
file.puts
|
@@ -1131,8 +1113,8 @@ def main_menu
|
|
1131
1113
|
:z => :z_interface,
|
1132
1114
|
:d => :child_dirs,
|
1133
1115
|
:r => :recent_files,
|
1134
|
-
'1' => :
|
1135
|
-
'2' => :
|
1116
|
+
'1' => :select_from_visited_files,
|
1117
|
+
'2' => :select_from_used_dirs,
|
1136
1118
|
:t => :dirtree,
|
1137
1119
|
'4' => :tree,
|
1138
1120
|
:s => :sort_menu,
|
@@ -1141,8 +1123,8 @@ def main_menu
|
|
1141
1123
|
:b => :bookmark_menu,
|
1142
1124
|
:y => :selection_menu,
|
1143
1125
|
:B => :bindkey_ext_command,
|
1144
|
-
:M => :
|
1145
|
-
'%' => :
|
1126
|
+
:M => :create_a_dir,
|
1127
|
+
'%' => :create_a_file,
|
1146
1128
|
'S' => :scripts,
|
1147
1129
|
:x => :extras
|
1148
1130
|
}
|
@@ -1163,38 +1145,14 @@ end
|
|
1163
1145
|
|
1164
1146
|
def bookmark_menu
|
1165
1147
|
h = {
|
1166
|
-
:
|
1167
|
-
:
|
1168
|
-
:
|
1148
|
+
v: :view_bookmarks,
|
1149
|
+
c: :create_bookmark,
|
1150
|
+
g: :goto_bookmark
|
1169
1151
|
}
|
1170
1152
|
menu 'Bookmark Menu', h
|
1171
1153
|
end
|
1172
1154
|
|
1173
|
-
#
|
1174
|
-
# 2019-03-08 - 23:46
|
1175
|
-
# FIXME returns a String not symbol, so some callers can fail
|
1176
|
-
def fzfmenu(title, h)
|
1177
|
-
return unless h
|
1178
|
-
|
1179
|
-
pbold title.to_s
|
1180
|
-
values = h.values.join("\n")
|
1181
|
-
binding = `echo "#{values}" | fzf --prompt="#{title.to_s} :"`
|
1182
|
-
# h.each_pair { |k, v| puts " #{k}: #{v}" }
|
1183
|
-
# ch = get_char
|
1184
|
-
# binding = h[ch]
|
1185
|
-
# binding ||= h[ch.to_sym]
|
1186
|
-
# FIXME we have converted symbol to string
|
1187
|
-
ch = nil
|
1188
|
-
if binding
|
1189
|
-
binding = binding.chomp
|
1190
|
-
send(binding) if respond_to?(binding, true)
|
1191
|
-
ch = h.key(binding)
|
1192
|
-
end
|
1193
|
-
[ch, binding]
|
1194
|
-
end
|
1195
|
-
|
1196
|
-
# this style used hotkeys which I remember. But it can get long.
|
1197
|
-
# and I have to fix a hotkey for each new entry
|
1155
|
+
# Create a menu using title, and hash of key and binding
|
1198
1156
|
def menu(title, h)
|
1199
1157
|
return unless h
|
1200
1158
|
|
@@ -1209,6 +1167,8 @@ def menu(title, h)
|
|
1209
1167
|
ch = get_char
|
1210
1168
|
binding = h[ch]
|
1211
1169
|
binding ||= h[ch.to_sym]
|
1170
|
+
# TODO: 2019-03-21 - menu's do not have comments, they are symbols
|
1171
|
+
# binding, _ = binding.split(':')
|
1212
1172
|
if binding
|
1213
1173
|
send(binding) if respond_to?(binding, true)
|
1214
1174
|
end
|
@@ -1219,7 +1179,6 @@ def toggle_menu
|
|
1219
1179
|
h = { :h => :toggle_hidden, :c => :toggle_case, :l => :toggle_long_list, '1' => :toggle_columns,
|
1220
1180
|
:p => :toggle_pager_mode, :e => :toggle_enhanced_list }
|
1221
1181
|
_, menu_text = menu 'Toggle Menu', h
|
1222
|
-
# NOTE fzfmenu returns string not symbol
|
1223
1182
|
return unless menu_text
|
1224
1183
|
|
1225
1184
|
case menu_text
|
@@ -1237,11 +1196,15 @@ def toggle_menu
|
|
1237
1196
|
when :toggle_columns
|
1238
1197
|
# FIXME: 2019-03-20 - if 3 then 1
|
1239
1198
|
# adjust stact and sta, if moving from panned position
|
1240
|
-
|
1199
|
+
if $gviscols == 1
|
1200
|
+
$gviscols = 3
|
1201
|
+
else
|
1202
|
+
$gviscols = 1
|
1203
|
+
end
|
1241
1204
|
# $long_listing = false if $gviscols > 1
|
1242
1205
|
x = $grows * $gviscols
|
1243
1206
|
$pagesize = $pagesize == x ? $grows : x
|
1244
|
-
|
1207
|
+
message "Visible columns now set to #{$gviscols}"
|
1245
1208
|
when :toggle_pager_mode
|
1246
1209
|
$editor_mode = !$editor_mode
|
1247
1210
|
$default_command = if $editor_mode
|
@@ -1258,9 +1221,11 @@ def toggle_menu
|
|
1258
1221
|
when :toggle_long_list
|
1259
1222
|
$long_listing = !$long_listing
|
1260
1223
|
if $long_listing
|
1224
|
+
$saved_gviscols = $gviscols
|
1261
1225
|
$gviscols = 1
|
1262
1226
|
$pagesize = $grows
|
1263
1227
|
else
|
1228
|
+
$gviscols = $saved_gviscols || 3
|
1264
1229
|
x = $grows * $gviscols
|
1265
1230
|
$pagesize = $pagesize == x ? $grows : x
|
1266
1231
|
end
|
@@ -1269,18 +1234,18 @@ def toggle_menu
|
|
1269
1234
|
$sta = $stact
|
1270
1235
|
$stact = 0 # in case user was panned 2019-03-20 -
|
1271
1236
|
end
|
1272
|
-
message "Long listing is #{$long_listing}"
|
1237
|
+
message "Long listing is #{$long_listing}, vis cols is #{$gviscols}"
|
1273
1238
|
refresh
|
1274
1239
|
end
|
1275
1240
|
end
|
1276
1241
|
|
1277
1242
|
def sort_menu
|
1278
1243
|
lo = nil
|
1279
|
-
h = {
|
1280
|
-
l: :largest, s: :smallest,
|
1244
|
+
h = { m: :modified, a: :accessed, M: :oldest,
|
1245
|
+
l: :largest, s: :smallest, n: :name, r: :rev_name, d: :dirs, c: :clear }
|
1281
1246
|
ch, menu_text = menu 'Sort Menu', h
|
1282
1247
|
case menu_text
|
1283
|
-
when :
|
1248
|
+
when :modified
|
1284
1249
|
lo = 'om'
|
1285
1250
|
when :accessed
|
1286
1251
|
lo = 'oa'
|
@@ -1292,7 +1257,7 @@ def sort_menu
|
|
1292
1257
|
lo = 'oL'
|
1293
1258
|
when :name
|
1294
1259
|
lo = 'on'
|
1295
|
-
when :
|
1260
|
+
when :rev_name
|
1296
1261
|
lo = 'On'
|
1297
1262
|
when :dirs
|
1298
1263
|
lo = '/'
|
@@ -1422,19 +1387,20 @@ def filter_for_current_extension
|
|
1422
1387
|
reduce extn
|
1423
1388
|
end
|
1424
1389
|
|
1425
|
-
def
|
1390
|
+
def select_from_used_dirs
|
1426
1391
|
$title = 'Used Directories'
|
1427
1392
|
home = File.expand_path '~'
|
1428
1393
|
$files = $used_dirs.uniq.map { |path| path.sub("#{home}", '~') }
|
1429
1394
|
end
|
1430
1395
|
|
1431
|
-
def
|
1396
|
+
def select_from_visited_files
|
1432
1397
|
# not yet a unique list, needs to be unique and have latest pushed to top
|
1433
1398
|
$title = 'Visited Files'
|
1434
1399
|
home = File.expand_path '~'
|
1435
1400
|
$files = $visited_files.uniq.map { |path| path.sub("#{home}", '~') }
|
1436
1401
|
end
|
1437
1402
|
|
1403
|
+
# maybe unused ??? XXX
|
1438
1404
|
def select_bookmarks
|
1439
1405
|
$title = 'Bookmarks'
|
1440
1406
|
$files = $bookmarks.values
|
@@ -1551,9 +1517,9 @@ end
|
|
1551
1517
|
def subcommand
|
1552
1518
|
print 'Enter command: q x wq p w e r h '
|
1553
1519
|
begin
|
1554
|
-
command =
|
1520
|
+
command = readline
|
1555
1521
|
return if command == ''
|
1556
|
-
rescue
|
1522
|
+
rescue StandardError => ex
|
1557
1523
|
return
|
1558
1524
|
end
|
1559
1525
|
if command == 'q'
|
@@ -1729,6 +1695,7 @@ def command_file(prompt, *command)
|
|
1729
1695
|
file = Shellwords.escape(file)
|
1730
1696
|
pbold "#{command} #{file} (#{pauseyn})"
|
1731
1697
|
system "#{command} #{file}"
|
1698
|
+
setup_terminal
|
1732
1699
|
pause if pauseyn == 'y'
|
1733
1700
|
refresh
|
1734
1701
|
else
|
@@ -1907,7 +1874,8 @@ def file_actions(action = nil)
|
|
1907
1874
|
when :zip
|
1908
1875
|
print 'Archive name: '
|
1909
1876
|
# target = gets().chomp
|
1910
|
-
target =
|
1877
|
+
target = readline
|
1878
|
+
return unless target
|
1911
1879
|
return if target == ''
|
1912
1880
|
|
1913
1881
|
# don't want a blank space or something screwing up
|
@@ -1916,6 +1884,7 @@ def file_actions(action = nil)
|
|
1916
1884
|
perror "Target (#{target}) exists"
|
1917
1885
|
else
|
1918
1886
|
system "tar zcvf #{target} #{files}"
|
1887
|
+
setup_terminal
|
1919
1888
|
refresh
|
1920
1889
|
end
|
1921
1890
|
end
|
@@ -1924,7 +1893,7 @@ def file_actions(action = nil)
|
|
1924
1893
|
# 2019-03-07 NOTE works for single file FIXME
|
1925
1894
|
# 2019-03-07 - TODO for n files replace pattern with string
|
1926
1895
|
print "rename #{text} to : "
|
1927
|
-
target =
|
1896
|
+
target = readline
|
1928
1897
|
return if target == ''
|
1929
1898
|
|
1930
1899
|
text = File.expand_path(text)
|
@@ -1937,6 +1906,7 @@ def file_actions(action = nil)
|
|
1937
1906
|
end
|
1938
1907
|
when :most, :less, :vim
|
1939
1908
|
system "#{menu_text} #{files}"
|
1909
|
+
setup_terminal
|
1940
1910
|
# should we remove from selection ?
|
1941
1911
|
|
1942
1912
|
when :remspace
|
@@ -1974,6 +1944,7 @@ def file_actions(action = nil)
|
|
1974
1944
|
pause
|
1975
1945
|
print
|
1976
1946
|
system "#{menu_text} #{files}"
|
1947
|
+
setup_terminal
|
1977
1948
|
refresh
|
1978
1949
|
pause
|
1979
1950
|
end
|
@@ -2026,7 +1997,7 @@ end
|
|
2026
1997
|
|
2027
1998
|
def ag
|
2028
1999
|
print 'Enter a pattern to search (ag): '
|
2029
|
-
pattern =
|
2000
|
+
pattern = readline
|
2030
2001
|
return if pattern == ''
|
2031
2002
|
|
2032
2003
|
$title = "Files found using 'ag' #{pattern}"
|
@@ -2042,7 +2013,7 @@ end
|
|
2042
2013
|
|
2043
2014
|
def ffind
|
2044
2015
|
print 'Enter a file name pattern to find: '
|
2045
|
-
pattern =
|
2016
|
+
pattern = readline
|
2046
2017
|
return if pattern == ''
|
2047
2018
|
|
2048
2019
|
$title = "Files found using 'find' #{pattern}"
|
@@ -2056,7 +2027,7 @@ end
|
|
2056
2027
|
|
2057
2028
|
def locate
|
2058
2029
|
print 'Enter a file name pattern to locate: '
|
2059
|
-
pattern =
|
2030
|
+
pattern = readline
|
2060
2031
|
return if pattern == ''
|
2061
2032
|
|
2062
2033
|
$title = "Files found using 'locate' #{pattern}"
|
@@ -2075,12 +2046,11 @@ end
|
|
2075
2046
|
#
|
2076
2047
|
def viminfo
|
2077
2048
|
file = File.expand_path('~/.viminfo')
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
end
|
2049
|
+
return unless File.exist? file
|
2050
|
+
$title = 'Files from ~/.viminfo'
|
2051
|
+
# $files = `grep '^>' ~/.viminfo | cut -d ' ' -f 2- | sed "s#~#$HOME#g"`.split("\n")
|
2052
|
+
$files = `grep '^>' ~/.viminfo | cut -d ' ' -f 2- `.split("\n")
|
2053
|
+
$files.select! { |x| x = File.expand_path(x); File.exist?(x) }
|
2084
2054
|
end
|
2085
2055
|
|
2086
2056
|
## takes directories from the z program, if you use autojump you can
|
@@ -2088,24 +2058,24 @@ end
|
|
2088
2058
|
#
|
2089
2059
|
def z_interface
|
2090
2060
|
file = File.expand_path('~/.z')
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
end
|
2061
|
+
return unless File.exist? file
|
2062
|
+
$title = 'Directories from ~/.z'
|
2063
|
+
$files = `sort -rn -k2 -t '|' ~/.z | cut -f1 -d '|'`.split("\n")
|
2064
|
+
home = ENV['HOME']
|
2065
|
+
# shorten file names
|
2066
|
+
$files.collect! do |f|
|
2067
|
+
f.sub(/#{home}/, '~')
|
2099
2068
|
end
|
2100
2069
|
end
|
2101
2070
|
|
2102
2071
|
def vidir
|
2103
|
-
system
|
2072
|
+
system 'vidir'
|
2073
|
+
setup_terminal
|
2104
2074
|
end
|
2105
2075
|
## there is no one consisten way i am getting.
|
2106
2076
|
# i need to do a shell join if I am to pipe ffiles to say: xargs ls -t
|
2107
2077
|
# but if i want to pipe names to grep xxx then i need to join with newlines
|
2108
|
-
def pipe; end
|
2078
|
+
# def pipe; end
|
2109
2079
|
|
2110
2080
|
## some cursor movement functions
|
2111
2081
|
# TODO: 2019-03-18 - cursor should also be updated
|
@@ -2304,10 +2274,10 @@ def revert_dir_pos
|
|
2304
2274
|
end
|
2305
2275
|
end
|
2306
2276
|
|
2307
|
-
def
|
2277
|
+
def create_a_dir
|
2308
2278
|
print
|
2309
2279
|
print 'Enter directory name: '
|
2310
|
-
str =
|
2280
|
+
str = readline
|
2311
2281
|
return if str == ''
|
2312
2282
|
|
2313
2283
|
if File.exist? str
|
@@ -2318,21 +2288,22 @@ def newdir
|
|
2318
2288
|
FileUtils.mkdir str
|
2319
2289
|
$used_dirs.insert(0, str) if File.exist?(str)
|
2320
2290
|
refresh
|
2321
|
-
rescue
|
2291
|
+
rescue StandardError => ex
|
2322
2292
|
perror "Error in newdir: #{ex}"
|
2323
2293
|
end
|
2324
2294
|
end
|
2325
2295
|
|
2326
|
-
def
|
2296
|
+
def create_a_file
|
2327
2297
|
print
|
2328
2298
|
print 'Enter file name: '
|
2329
|
-
str =
|
2299
|
+
str = readline
|
2330
2300
|
return if str == ''
|
2331
2301
|
|
2332
2302
|
# FIXME a file with space will not create single file
|
2333
2303
|
# 2019-03-10 - maybe touch a file
|
2334
2304
|
|
2335
2305
|
system %($EDITOR "#{str}")
|
2306
|
+
setup_terminal
|
2336
2307
|
$visited_files.insert(0, str) if File.exist?(str)
|
2337
2308
|
refresh
|
2338
2309
|
end
|
@@ -2350,9 +2321,11 @@ end
|
|
2350
2321
|
|
2351
2322
|
# ------------------- scripts ------------------ #
|
2352
2323
|
# prompt for scripts to execute, giving selected file names
|
2324
|
+
# NOTE: TODO 2019-03-21 - some scripts can output a filelist to display
|
2353
2325
|
def scripts
|
2354
2326
|
title = 'Select a script'
|
2355
2327
|
script_path = '~/.config/cetus/scripts'
|
2328
|
+
# TODO write selected files to a known file before calling
|
2356
2329
|
binding = `find #{script_path} -type f | fzf --prompt="#{title.to_s} :"`
|
2357
2330
|
return unless binding
|
2358
2331
|
|
@@ -2377,12 +2350,14 @@ def view_selected_files
|
|
2377
2350
|
$selected_files.each { |row| file.puts row }
|
2378
2351
|
file.flush
|
2379
2352
|
system "$PAGER #{file.path}"
|
2353
|
+
setup_terminal
|
2380
2354
|
rescue
|
2381
2355
|
file.close
|
2382
2356
|
file.unlink
|
2383
2357
|
end
|
2384
2358
|
end
|
2385
2359
|
# ------------- end of view_selected_files --------------------------------#
|
2360
|
+
|
2386
2361
|
##
|
2387
2362
|
# Editing of the User Dir List.
|
2388
2363
|
# remove current entry from used dirs list, since we may not want some entries being there
|
@@ -2504,13 +2479,14 @@ def enhance_file_list
|
|
2504
2479
|
end
|
2505
2480
|
end
|
2506
2481
|
|
2482
|
+
# insert important files to end of $files
|
2507
2483
|
def insert_into_list(_dir, file)
|
2508
2484
|
# ix = $files.index(dir)
|
2509
2485
|
# raise "something wrong can find #{dir}." unless ix
|
2510
2486
|
# $files.insert ix, *file
|
2511
2487
|
# 2013-03-19 - 19:42 adding at end to avoid confusion
|
2512
2488
|
# $files.concat file
|
2513
|
-
$files.push
|
2489
|
+
$files.push(*file)
|
2514
2490
|
end
|
2515
2491
|
|
2516
2492
|
def get_important_files(dir)
|
@@ -2530,6 +2506,7 @@ def get_important_files(dir)
|
|
2530
2506
|
list
|
2531
2507
|
end
|
2532
2508
|
|
2509
|
+
# set message which will be displayed in status line
|
2533
2510
|
def message mess
|
2534
2511
|
$message = mess
|
2535
2512
|
end
|
@@ -2539,6 +2516,8 @@ Signal.trap('EXIT') do
|
|
2539
2516
|
# system 'tput rmcup'
|
2540
2517
|
exit
|
2541
2518
|
end
|
2519
|
+
|
2520
|
+
setup_terminal
|
2542
2521
|
run
|
2543
2522
|
# 2019-02-20 - added so alt-screen is used
|
2544
2523
|
system 'tput rmcup'
|
data/cetus.gemspec
CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'cetus'
|
8
|
-
spec.version = '0.1.
|
8
|
+
spec.version = '0.1.28'
|
9
9
|
spec.authors = ['Rahul Kumar']
|
10
10
|
spec.email = ['oneness.univ@gmail.com']
|
11
11
|
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.1.
|
4
|
+
version: 0.1.28
|
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-03-
|
11
|
+
date: 2019-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|