cetus 0.1.21 → 0.1.22
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/bin/cetus +1040 -711
- data/cetus.gemspec +10 -10
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 040badb6cd9462f5d5a2fe5f5b5e320c03fbbd80984d71e526c500bdd0781822
|
4
|
+
data.tar.gz: c48f55c076c32815785341986791e680b990b3fbf3bf1d519835b70331790a52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7a6655724e7b3e5e46d20d8bf0cc90a3032aacdca0dbbbb4d4348c87c845e8a974574f2530781ff44a7860ed1d3f9eb8e0c5caa952411963106ac3622fc39f9
|
7
|
+
data.tar.gz: c61c40989b45d3e4c2ecc04d6a04ceae2722fbf3d0d582e37fb86b4e00b5d78582c16edd18fef1c58ad86e3c20038d4ae3b5455270c7da25dba2bcdb19f27c75
|
data/bin/cetus
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
2
|
+
# --------------------------------------------------------------------------- #
|
3
3
|
# File: cetus
|
4
4
|
# Description: Fast file navigation, a tiny version of zfm
|
5
5
|
# but with a different indexing mechanism
|
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-
|
10
|
-
#
|
11
|
-
# cetus.rb Copyright (C) 2012-
|
9
|
+
# Last update: 2019-03-10 15:07
|
10
|
+
# --------------------------------------------------------------------------- #
|
11
|
+
# cetus.rb Copyright (C) 2012-2019 rahul kumar
|
12
12
|
# == CHANGELOG
|
13
13
|
# 2019-02-20 - added smcup and rmcup so alt-screen is used. works a bit
|
14
14
|
# 2019-03-04 - change clear to go to 0,0 and clear down to reduce pollution
|
15
15
|
# 2019-03-04 - changed quit to q (earlier Q)
|
16
16
|
# 2019-03-04 - first dirs then files
|
17
|
+
# 2019-03-10 - changing selected_files to have fullpath
|
17
18
|
# == TODO
|
18
19
|
# To dirs add GEMHOME RUBYLIB PYTHONILB or PYTHONPATH,
|
19
20
|
# Make rubygem aware : gemspec or Gemfile the expand lib and bin
|
@@ -23,10 +24,9 @@ require 'readline'
|
|
23
24
|
require 'io/wait'
|
24
25
|
# http://www.ruby-doc.org/stdlib-1.9.3/libdoc/shellwords/rdoc/Shellwords.html
|
25
26
|
require 'shellwords'
|
27
|
+
# https://docs.ruby-lang.org/en/2.6.0/FileUtils.html
|
26
28
|
require 'fileutils'
|
27
29
|
# -- requires 1.9.3 for io/wait
|
28
|
-
# -- cannot do with Highline since we need a timeout on wait,
|
29
|
-
# not sure if HL can do that
|
30
30
|
|
31
31
|
## INSTALLATION
|
32
32
|
# copy into PATH
|
@@ -35,113 +35,119 @@ require 'fileutils'
|
|
35
35
|
|
36
36
|
# 2019-02-20 - added so alt-screen is used
|
37
37
|
system 'tput smcup'
|
38
|
-
VERSION = '0.1.
|
38
|
+
VERSION = '0.1.22.0'.freeze
|
39
39
|
O_CONFIG = true
|
40
|
-
CONFIG_FILE = '~/.lyrainfo'
|
40
|
+
# CONFIG_FILE = '~/.lyrainfo'.freeze
|
41
|
+
CONFIG_FILE = '~/.config/cetus/conf.yml'.freeze
|
41
42
|
|
42
43
|
$bindings = {}
|
43
44
|
$bindings = {
|
44
|
-
'`'
|
45
|
-
'='
|
46
|
-
'!'
|
47
|
-
'@'
|
45
|
+
'`' => 'main_menu',
|
46
|
+
'=' => 'toggle_menu',
|
47
|
+
'!' => 'command_mode',
|
48
|
+
'@' => 'selection_mode_toggle',
|
48
49
|
'M-a' => 'select_all',
|
49
50
|
'M-A' => 'unselect_all',
|
50
|
-
','
|
51
|
-
'
|
52
|
-
'
|
53
|
-
'
|
54
|
-
|
55
|
-
'
|
56
|
-
'
|
57
|
-
'
|
58
|
-
'
|
59
|
-
'M-
|
60
|
-
'
|
61
|
-
'M-
|
62
|
-
'M-
|
63
|
-
'M-
|
64
|
-
'
|
65
|
-
'
|
66
|
-
'
|
67
|
-
'
|
68
|
-
'
|
69
|
-
'
|
70
|
-
'
|
71
|
-
'
|
72
|
-
'
|
73
|
-
|
74
|
-
'
|
75
|
-
'
|
76
|
-
'
|
77
|
-
'
|
78
|
-
|
79
|
-
'
|
80
|
-
'
|
81
|
-
'
|
82
|
-
'
|
83
|
-
'C-
|
84
|
-
'
|
85
|
-
'
|
86
|
-
'
|
51
|
+
',' => 'goto_parent_dir',
|
52
|
+
'~' => 'goto_home_dir',
|
53
|
+
'-' => 'goto_previous_dir', # 2019-03-07 - added. like 'cd ='
|
54
|
+
'+' => 'goto_dir', # 2019-03-07 - TODO: change binding
|
55
|
+
'.' => 'pop_dir',
|
56
|
+
':' => 'subcommand',
|
57
|
+
"'" => 'goto_bookmark',
|
58
|
+
'/' => 'enter_regex',
|
59
|
+
'M-p' => 'prev_page',
|
60
|
+
'M-n' => 'next_page',
|
61
|
+
'SPACE' => 'next_page',
|
62
|
+
'M-f' => 'select_visited_files',
|
63
|
+
'M-d' => 'select_used_dirs',
|
64
|
+
'M-b' => 'select_bookmarks',
|
65
|
+
'M-m' => 'create_bookmark',
|
66
|
+
'M-M' => 'show_marks',
|
67
|
+
'C-c' => 'escape',
|
68
|
+
'ESCAPE' => 'escape',
|
69
|
+
'TAB' => 'views',
|
70
|
+
'C-i' => 'views',
|
71
|
+
'?' => 'dirtree',
|
72
|
+
'ENTER' => 'select_current',
|
73
|
+
'C-p' => 'page_current',
|
74
|
+
'C-e' => 'edit_current',
|
75
|
+
'C-o' => 'edit_current',
|
76
|
+
'D' => 'delete_file',
|
77
|
+
'M' => 'file_actions most',
|
78
|
+
'q' => 'quit_command', # was Q now q 2019-03-04 -
|
79
|
+
# "RIGHT" => "column_next",
|
80
|
+
'RIGHT' => 'select_current', # changed 2018-03-12 - for faster navigation
|
81
|
+
'LEFT' => 'goto_parent_dir', # changed on 2018-03-12 - earlier column_next 1
|
82
|
+
']' => 'column_next',
|
83
|
+
'[' => 'column_next 1',
|
84
|
+
'C-x' => 'file_actions',
|
85
|
+
'M--' => 'columns_incdec -1',
|
86
|
+
'M-+' => 'columns_incdec 1',
|
87
|
+
'S' => 'command_file list y ls -lh',
|
88
|
+
'L' => 'command_file Page n less',
|
89
|
+
'C-d' => 'cursor_scroll_dn',
|
90
|
+
'C-b' => 'cursor_scroll_up',
|
91
|
+
'UP' => 'cursor_up',
|
92
|
+
'DOWN' => 'cursor_dn',
|
87
93
|
'C-SPACE' => 'visual_mode_toggle',
|
88
94
|
|
89
|
-
'M-?'
|
90
|
-
'F1'
|
91
|
-
'F2'
|
92
|
-
'F3'
|
93
|
-
'F4'
|
94
|
-
'S-F1'
|
95
|
-
'S-F2'
|
95
|
+
'M-?' => 'print_help',
|
96
|
+
'F1' => 'print_help',
|
97
|
+
'F2' => 'child_dirs',
|
98
|
+
'F3' => 'dirtree',
|
99
|
+
'F4' => 'tree',
|
100
|
+
'S-F1' => 'dirtree',
|
101
|
+
'S-F2' => 'tree'
|
96
102
|
|
97
103
|
}
|
98
104
|
|
99
105
|
## clean this up a bit, copied from shell program and macro'd
|
100
|
-
$kh=
|
101
|
-
$kh["
|
102
|
-
$kh["
|
103
|
-
$kh["
|
104
|
-
$kh['']=
|
105
|
-
KEY_PGDN="
|
106
|
-
KEY_PGUP="
|
106
|
+
$kh = {}
|
107
|
+
$kh["\eOP"] = 'F1'
|
108
|
+
$kh["\e[A"] = 'UP'
|
109
|
+
$kh["\e[5~"] = 'PGUP'
|
110
|
+
$kh[''] = 'ESCAPE'
|
111
|
+
KEY_PGDN = "\e[6~".freeze
|
112
|
+
KEY_PGUP = "\e[5~".freeze
|
107
113
|
## I needed to replace the O with a [ for this to work
|
108
114
|
# in Vim Home comes as ^[OH whereas on the command line it is correct as ^[[H
|
109
|
-
KEY_HOME='[H'
|
110
|
-
KEY_END="
|
111
|
-
KEY_F1="
|
112
|
-
KEY_UP="
|
113
|
-
KEY_DOWN="
|
114
|
-
|
115
|
-
$kh[KEY_PGDN]=
|
116
|
-
$kh[KEY_PGUP]=
|
117
|
-
$kh[KEY_HOME]=
|
118
|
-
$kh[KEY_END]=
|
119
|
-
$kh[KEY_F1]=
|
120
|
-
$kh[KEY_UP]=
|
121
|
-
$kh[KEY_DOWN]=
|
122
|
-
KEY_LEFT='[D'
|
123
|
-
KEY_RIGHT='[C'
|
124
|
-
$kh["
|
125
|
-
$kh["
|
126
|
-
$kh["
|
127
|
-
$kh[KEY_LEFT] =
|
128
|
-
$kh[KEY_RIGHT]=
|
129
|
-
KEY_F5='[15~'
|
130
|
-
KEY_F6='[17~'
|
131
|
-
KEY_F7='[18~'
|
132
|
-
KEY_F8='[19~'
|
133
|
-
KEY_F9='[20~'
|
134
|
-
KEY_F10='[21~'
|
135
|
-
KEY_S_F1='[1;2P'
|
136
|
-
$kh[KEY_F5]=
|
137
|
-
$kh[KEY_F6]=
|
138
|
-
$kh[KEY_F7]=
|
139
|
-
$kh[KEY_F8]=
|
140
|
-
$kh[KEY_F9]=
|
141
|
-
$kh[KEY_F10]=
|
115
|
+
KEY_HOME = '[H'.freeze
|
116
|
+
KEY_END = "\e[F".freeze
|
117
|
+
KEY_F1 = "\eOP".freeze
|
118
|
+
KEY_UP = "\e[A".freeze
|
119
|
+
KEY_DOWN = "\e[B".freeze
|
120
|
+
|
121
|
+
$kh[KEY_PGDN] = 'PgDn'
|
122
|
+
$kh[KEY_PGUP] = 'PgUp'
|
123
|
+
$kh[KEY_HOME] = 'Home'
|
124
|
+
$kh[KEY_END] = 'End'
|
125
|
+
$kh[KEY_F1] = 'F1'
|
126
|
+
$kh[KEY_UP] = 'UP'
|
127
|
+
$kh[KEY_DOWN] = 'DOWN'
|
128
|
+
KEY_LEFT = '[D'.freeze
|
129
|
+
KEY_RIGHT = '[C'.freeze
|
130
|
+
$kh["\eOQ"] = 'F2'
|
131
|
+
$kh["\eOR"] = 'F3'
|
132
|
+
$kh["\eOS"] = 'F4'
|
133
|
+
$kh[KEY_LEFT] = 'LEFT'
|
134
|
+
$kh[KEY_RIGHT] = 'RIGHT'
|
135
|
+
KEY_F5 = '[15~'.freeze
|
136
|
+
KEY_F6 = '[17~'.freeze
|
137
|
+
KEY_F7 = '[18~'.freeze
|
138
|
+
KEY_F8 = '[19~'.freeze
|
139
|
+
KEY_F9 = '[20~'.freeze
|
140
|
+
KEY_F10 = '[21~'.freeze
|
141
|
+
KEY_S_F1 = '[1;2P'.freeze
|
142
|
+
$kh[KEY_F5] = 'F5'
|
143
|
+
$kh[KEY_F6] = 'F6'
|
144
|
+
$kh[KEY_F7] = 'F7'
|
145
|
+
$kh[KEY_F8] = 'F8'
|
146
|
+
$kh[KEY_F9] = 'F9'
|
147
|
+
$kh[KEY_F10] = 'F10'
|
142
148
|
# testing out shift+Function. these are the codes my kb generates
|
143
|
-
$kh[KEY_S_F1]=
|
144
|
-
$kh['[1;2Q']=
|
149
|
+
$kh[KEY_S_F1] = 'S-F1'
|
150
|
+
$kh['[1;2Q'] = 'S-F2'
|
145
151
|
|
146
152
|
def old_clear_screen
|
147
153
|
system 'clear'
|
@@ -169,16 +175,16 @@ end
|
|
169
175
|
# copied from fff
|
170
176
|
# Call before shelling to editor pager and when exiting
|
171
177
|
def reset_terminal
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
178
|
+
# Reset the terminal to a useable state (undo all changes).
|
179
|
+
# '\e[?7h': Re-enable line wrapping.
|
180
|
+
# '\e[?25h': Unhide the cursor.
|
181
|
+
# '\e[2J': Clear the terminal.
|
182
|
+
# '\e[;r': Set the scroll region to its default value.
|
183
|
+
# Also sets cursor to (0,0).
|
184
|
+
print "\e[?7h\e[?25h\e[2J\e[;r"
|
179
185
|
|
180
|
-
|
181
|
-
|
186
|
+
# Show user input.
|
187
|
+
system 'stty echo'
|
182
188
|
end
|
183
189
|
|
184
190
|
# copied from fff
|
@@ -197,107 +203,115 @@ def setup_terminal
|
|
197
203
|
system 'stty -echo'
|
198
204
|
end
|
199
205
|
|
206
|
+
# wrap readline so C-c can be ignored, but blank is taken as default
|
207
|
+
def readline
|
208
|
+
begin
|
209
|
+
target = Readline.readline('>', true)
|
210
|
+
rescue Interrupt
|
211
|
+
return nil
|
212
|
+
end
|
213
|
+
target
|
214
|
+
end
|
215
|
+
|
200
216
|
## get a character from user and return as a string
|
201
217
|
# Adapted from:
|
202
|
-
#http://stackoverflow.com/questions/174933/how-to-get-a-single-character-without-pressing-enter/8274275#8274275
|
218
|
+
# http://stackoverflow.com/questions/174933/how-to-get-a-single-character-without-pressing-enter/8274275#8274275
|
203
219
|
# Need to take complex keys and matc against a hash.
|
204
220
|
def get_char
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
return "M-#{k.chr}"
|
239
|
-
end
|
240
|
-
return buff
|
221
|
+
system('stty raw -echo 2>/dev/null') # turn raw input on
|
222
|
+
c = nil
|
223
|
+
# if $stdin.ready?
|
224
|
+
c = $stdin.getc
|
225
|
+
cn = c.ord
|
226
|
+
return 'ENTER' if cn == 10 || cn == 13
|
227
|
+
return 'BACKSPACE' if cn == 127
|
228
|
+
return 'C-SPACE' if cn == 0
|
229
|
+
return 'SPACE' if cn == 32
|
230
|
+
# next does not seem to work, you need to bind C-i
|
231
|
+
return 'TAB' if cn == 8
|
232
|
+
|
233
|
+
if cn >= 0 && cn < 27
|
234
|
+
x = cn + 96
|
235
|
+
return "C-#{x.chr}"
|
236
|
+
end
|
237
|
+
if c == ''
|
238
|
+
buff = c.chr
|
239
|
+
loop do
|
240
|
+
k = nil
|
241
|
+
if $stdin.ready?
|
242
|
+
k = $stdin.getc
|
243
|
+
# puts "got #{k}"
|
244
|
+
buff += k.chr
|
245
|
+
else
|
246
|
+
x = $kh[buff]
|
247
|
+
return x if x
|
248
|
+
|
249
|
+
# puts "returning with #{buff}"
|
250
|
+
if buff.size == 2
|
251
|
+
## possibly a meta/alt char
|
252
|
+
k = buff[-1]
|
253
|
+
return "M-#{k.chr}"
|
241
254
|
end
|
255
|
+
return buff
|
242
256
|
end
|
243
257
|
end
|
244
|
-
#end
|
245
|
-
return c.chr if c
|
246
|
-
ensure
|
247
|
-
#system "stty -raw echo" # turn raw input off
|
248
|
-
system('stty -raw echo 2>/dev/null') # turn raw input on
|
249
258
|
end
|
259
|
+
# end
|
260
|
+
return c.chr if c
|
261
|
+
ensure
|
262
|
+
# system "stty -raw echo" # turn raw input off
|
263
|
+
system('stty -raw echo 2>/dev/null') # turn raw input on
|
250
264
|
end
|
251
265
|
|
252
266
|
## GLOBALS
|
253
|
-
|
254
|
-
|
255
|
-
$IDX=('a'..'y').to_a
|
267
|
+
# $IDX="123456789abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
268
|
+
# $IDX="abcdefghijklmnopqrstuvwxy"
|
269
|
+
$IDX = ('a'..'y').to_a
|
256
270
|
$IDX.delete 'q'
|
257
271
|
$IDX.concat ('za'..'zz').to_a
|
258
272
|
$IDX.concat ('Za'..'Zz').to_a
|
259
273
|
$IDX.concat ('ZA'..'ZZ').to_a
|
260
274
|
|
261
|
-
$selected_files =
|
275
|
+
$selected_files = []
|
262
276
|
$bookmarks = {}
|
263
277
|
$mode = nil
|
264
|
-
$glines
|
265
|
-
$gcols
|
278
|
+
$glines = `tput lines`.to_i
|
279
|
+
$gcols = `tput cols`.to_i
|
266
280
|
$grows = $glines - 3
|
267
281
|
$pagesize = 60
|
268
282
|
$gviscols = 3
|
269
283
|
$pagesize = $grows * $gviscols
|
270
284
|
$stact = 0
|
271
|
-
|
285
|
+
# $editor_mode = true
|
272
286
|
$editor_mode = false # changed 2018-03-12 - so we start in pager mode
|
273
287
|
$enhanced_mode = true
|
274
288
|
$visual_block_start = nil
|
275
289
|
$pager_command = {
|
276
|
-
:
|
277
|
-
:
|
278
|
-
:
|
279
|
-
:
|
290
|
+
text: 'most',
|
291
|
+
image: 'open',
|
292
|
+
zip: 'tar ztvf %% | most',
|
293
|
+
unknown: 'open'
|
280
294
|
}
|
281
295
|
$dir_position = {}
|
282
296
|
## CONSTANTS
|
283
|
-
GMARK='*'
|
284
|
-
CURMARK='>'
|
297
|
+
GMARK = '*'.freeze
|
298
|
+
CURMARK = '>'.freeze
|
285
299
|
MSCROLL = 10
|
286
|
-
SPACE=
|
287
|
-
CLEAR = "\e[0m"
|
288
|
-
BOLD = "\e[1m"
|
289
|
-
BOLD_OFF
|
290
|
-
RED
|
291
|
-
ON_RED
|
292
|
-
GREEN = "\e[32m"
|
293
|
-
YELLOW = "\e[33m"
|
294
|
-
BLUE = "\e[1;34m"
|
295
|
-
|
296
|
-
ON_BLUE = "\e[44m"
|
297
|
-
REVERSE = "\e[7m"
|
298
|
-
UNDERLINE = "\e[4m"
|
300
|
+
SPACE = ' '.freeze
|
301
|
+
CLEAR = "\e[0m".freeze
|
302
|
+
BOLD = "\e[1m".freeze
|
303
|
+
BOLD_OFF = "\e[22m".freeze
|
304
|
+
RED = "\e[31m".freeze
|
305
|
+
ON_RED = "\e[41m".freeze
|
306
|
+
GREEN = "\e[32m".freeze
|
307
|
+
YELLOW = "\e[33m".freeze
|
308
|
+
BLUE = "\e[1;34m".freeze
|
309
|
+
|
310
|
+
ON_BLUE = "\e[44m".freeze
|
311
|
+
REVERSE = "\e[7m".freeze
|
312
|
+
UNDERLINE = "\e[4m".freeze
|
299
313
|
CURSOR_COLOR = ON_BLUE
|
300
|
-
$patt=nil
|
314
|
+
$patt = nil
|
301
315
|
$ignorecase = true
|
302
316
|
$quitting = false
|
303
317
|
$modified = $writing = false
|
@@ -306,20 +320,20 @@ $visited_files = []
|
|
306
320
|
$visited_dirs = []
|
307
321
|
## dirs where some work has been done, for saving and restoring
|
308
322
|
$used_dirs = []
|
309
|
-
$default_sort_order =
|
323
|
+
$default_sort_order = 'om'
|
310
324
|
$sorto = $default_sort_order
|
311
325
|
$viewctr = 0
|
312
326
|
$history = []
|
313
327
|
$sta = $cursor = 0
|
314
328
|
$visual_mode = false
|
315
|
-
|
329
|
+
# $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} Command Mode #{BOLD}@#{BOLD_OFF} Selection Mode #{BOLD}q#{BOLD_OFF} Quit"
|
316
330
|
|
317
331
|
$help = "#{BOLD}M-?#{BOLD_OFF} Help #{BOLD}`#{BOLD_OFF} Menu #{BOLD}!#{BOLD_OFF} Command #{BOLD}=#{BOLD_OFF} Toggle #{BOLD}@#{BOLD_OFF} Selection Mode #{BOLD}q#{BOLD_OFF} Quit "
|
318
332
|
|
319
|
-
|
333
|
+
## main loop which calls all other programs
|
320
334
|
def run
|
321
|
-
home=ENV['HOME']
|
322
|
-
ctr=0
|
335
|
+
home = ENV['HOME']
|
336
|
+
ctr = 0
|
323
337
|
config_read
|
324
338
|
$files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}M)'`.split("\n")
|
325
339
|
$files = sort_file_list $files
|
@@ -327,27 +341,27 @@ def run
|
|
327
341
|
## added by RK 2014-03-31 - 00:29 since too many duplicates
|
328
342
|
$files = $files.uniq if $enhanced_mode
|
329
343
|
|
330
|
-
fl
|
344
|
+
fl = $files.size
|
331
345
|
|
332
346
|
selectedix = nil
|
333
|
-
$patt=
|
334
|
-
$sta=0
|
335
|
-
|
347
|
+
$patt = ''
|
348
|
+
$sta = 0
|
349
|
+
loop do
|
336
350
|
i = 0
|
337
|
-
if $patt
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
fl
|
351
|
+
$view = if $patt
|
352
|
+
if $ignorecase
|
353
|
+
$files.grep(/#{$patt}/i)
|
354
|
+
else
|
355
|
+
$files.grep(/#{$patt}/)
|
356
|
+
end
|
357
|
+
else
|
358
|
+
$files
|
359
|
+
end
|
360
|
+
fl = $view.size
|
347
361
|
$sta = 0 if $sta >= fl || $sta < 0
|
348
362
|
$viewport = $view[$sta, $pagesize]
|
349
363
|
fin = $sta + $viewport.size
|
350
|
-
$title ||= Dir.pwd.sub(home,
|
364
|
+
$title ||= Dir.pwd.sub(home, '~')
|
351
365
|
clear_screen
|
352
366
|
# title
|
353
367
|
print "#{GREEN}#{$help} #{BLUE}cetus #{VERSION}#{CLEAR}\n"
|
@@ -355,36 +369,34 @@ def run
|
|
355
369
|
t = t[t.size - $gcols..-1] if t.size >= $gcols
|
356
370
|
print "#{BOLD}#{t}#{CLEAR}\n"
|
357
371
|
## nilling the title means a superimposed one gets cleared.
|
358
|
-
|
372
|
+
# $title = nil
|
359
373
|
# split into 2 procedures so columnate can e clean and reused.
|
360
|
-
buff =
|
374
|
+
buff = _format $viewport
|
361
375
|
buff = columnate buff, $grows
|
362
376
|
# needed the next line to see how much extra we were going in padding
|
363
|
-
#buff.each {|line| print "#{REVERSE}#{line}#{CLEAR}\n" }
|
364
|
-
buff.each {|line| print line, "\n"
|
377
|
+
# buff.each {|line| print "#{REVERSE}#{line}#{CLEAR}\n" }
|
378
|
+
buff.each { |line| print line, "\n" }
|
365
379
|
print
|
366
380
|
# prompt
|
367
|
-
#print "#{$files.size}, #{view.size} sta=#{sta} (#{patt}): "
|
368
|
-
_mm =
|
381
|
+
# print "#{$files.size}, #{view.size} sta=#{sta} (#{patt}): "
|
382
|
+
_mm = ''
|
369
383
|
_mm = "[#{$mode}] " if $mode
|
370
384
|
print "\r#{_mm}#{$patt} >"
|
371
385
|
ch = get_char
|
372
|
-
#puts
|
373
|
-
#break if ch == "q"
|
374
|
-
#elsif ch =~ /^[1-9a-zA-Z]$/
|
386
|
+
# puts
|
387
|
+
# break if ch == "q"
|
388
|
+
# elsif ch =~ /^[1-9a-zA-Z]$/
|
375
389
|
# 2019-03-04 - ignore q since that is quit key now
|
376
|
-
#if ch =~ /^[a-zZ]$/
|
390
|
+
# if ch =~ /^[a-zZ]$/
|
377
391
|
if ch =~ /^[a-pr-zZ]$/
|
378
392
|
# hint mode
|
379
393
|
select_hint $viewport, ch
|
380
394
|
ctr = 0
|
381
|
-
elsif ch ==
|
382
|
-
if $patt &&
|
383
|
-
$patt = $patt[0..-2]
|
384
|
-
end
|
395
|
+
elsif ch == 'BACKSPACE'
|
396
|
+
$patt = $patt[0..-2] if $patt && !$patt.empty?
|
385
397
|
ctr = 0
|
386
398
|
else
|
387
|
-
#binding = $bindings[ch]
|
399
|
+
# binding = $bindings[ch]
|
388
400
|
x = $bindings[ch]
|
389
401
|
x = x.split if x
|
390
402
|
if x
|
@@ -392,57 +404,56 @@ def run
|
|
392
404
|
args = x
|
393
405
|
send(binding, *args) if binding
|
394
406
|
else
|
395
|
-
|
407
|
+
perror "No binding for #{ch}"
|
396
408
|
end
|
397
|
-
#p ch
|
409
|
+
# p ch
|
398
410
|
end
|
399
411
|
break if $quitting
|
400
412
|
end
|
401
413
|
write_curdir
|
402
|
-
puts
|
414
|
+
puts 'bye'
|
403
415
|
config_write if $writing
|
404
416
|
end
|
405
417
|
|
406
418
|
## write current dir to a file so we can ccd to it when exiting
|
407
419
|
def write_curdir
|
408
|
-
|
409
|
-
f = File.expand_path("~/.fff_d")
|
420
|
+
f = File.expand_path('~/.fff_d')
|
410
421
|
s = Dir.pwd
|
411
|
-
File.open(f,
|
422
|
+
File.open(f, 'w') do |f2|
|
412
423
|
f2.puts s
|
413
424
|
end
|
414
|
-
#puts "Written #{s} to #{f}"
|
425
|
+
# puts "Written #{s} to #{f}"
|
415
426
|
end
|
416
427
|
|
417
|
-
|
418
428
|
## code related to long listing of files
|
419
|
-
GIGA_SIZE =
|
420
|
-
MEGA_SIZE =
|
429
|
+
GIGA_SIZE = 1_073_741_824.0
|
430
|
+
MEGA_SIZE = 1_048_576.0
|
421
431
|
KILO_SIZE = 1024.0
|
422
432
|
|
423
433
|
# Return the file size with a readable style.
|
434
|
+
# NOTE format is a kernel method.
|
424
435
|
def readable_file_size(size, precision)
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
when size < GIGA_SIZE then "%.#{precision}f M" % (size / MEGA_SIZE)
|
430
|
-
else "%.#{precision}f G" % (size / GIGA_SIZE)
|
436
|
+
if size < KILO_SIZE then format('%d B', size)
|
437
|
+
elsif size < MEGA_SIZE then format("%.#{precision}f K", (size / KILO_SIZE))
|
438
|
+
elsif size < GIGA_SIZE then format("%.#{precision}f M", (size / MEGA_SIZE))
|
439
|
+
else format("%.#{precision}f G", (size / GIGA_SIZE))
|
431
440
|
end
|
432
441
|
end
|
442
|
+
|
433
443
|
## format date for file given stat
|
434
|
-
def date_format
|
435
|
-
t.strftime
|
444
|
+
def date_format(t)
|
445
|
+
t.strftime '%Y/%m/%d'
|
436
446
|
end
|
447
|
+
|
437
448
|
##
|
438
449
|
#
|
439
450
|
# print in columns
|
440
451
|
# ary - array of data
|
441
452
|
# sz - lines in one column
|
442
453
|
#
|
443
|
-
def columnate
|
444
|
-
buff=
|
445
|
-
return buff if ary.nil? || ary.
|
454
|
+
def columnate(ary, sz)
|
455
|
+
buff = []
|
456
|
+
return buff if ary.nil? || ary.empty?
|
446
457
|
|
447
458
|
# determine width based on number of files to show
|
448
459
|
# if less than sz then 1 col and full width
|
@@ -454,39 +465,35 @@ def columnate ary, sz
|
|
454
465
|
if ars <= sz
|
455
466
|
wid = $gcols - d
|
456
467
|
else
|
457
|
-
tmp = (ars * 1.000/ sz).ceil
|
468
|
+
tmp = (ars * 1.000 / sz).ceil
|
458
469
|
wid = $gcols / tmp - d
|
459
470
|
end
|
460
|
-
#elsif ars < sz * 2
|
461
|
-
|
462
|
-
#elsif ars < sz * 3
|
463
|
-
|
464
|
-
#else
|
465
|
-
|
466
|
-
#end
|
471
|
+
# elsif ars < sz * 2
|
472
|
+
# wid = $gcols/2 - d
|
473
|
+
# elsif ars < sz * 3
|
474
|
+
# wid = $gcols/3 - d
|
475
|
+
# else
|
476
|
+
# wid = $gcols/$gviscols - d
|
477
|
+
# end
|
467
478
|
|
468
479
|
# ix refers to the index in the complete file list, wherease we only show 60 at a time
|
469
|
-
ix=0
|
470
|
-
|
480
|
+
ix = 0
|
481
|
+
loop do
|
471
482
|
## ctr refers to the index in the column
|
472
|
-
ctr=0
|
483
|
+
ctr = 0
|
473
484
|
while ctr < sz
|
474
485
|
|
475
486
|
f = ary[ix]
|
476
487
|
fsz = f.size
|
477
488
|
if fsz > wid
|
478
|
-
f = f[0, wid-2]+
|
489
|
+
f = f[0, wid - 2] + '$ '
|
479
490
|
## we do the coloring after trunc so ANSI escpe seq does not get get
|
480
|
-
if ix + $sta == $cursor
|
481
|
-
f = "#{CURSOR_COLOR}#{f}#{CLEAR}"
|
482
|
-
end
|
491
|
+
f = "#{CURSOR_COLOR}#{f}#{CLEAR}" if ix + $sta == $cursor
|
483
492
|
else
|
484
493
|
## we do the coloring before padding so the entire line does not get padded, only file name
|
485
|
-
if ix + $sta == $cursor
|
486
|
-
|
487
|
-
|
488
|
-
#f = f.ljust(wid)
|
489
|
-
f << " " * (wid-fsz)
|
494
|
+
f = "#{CURSOR_COLOR}#{f}#{CLEAR}" if ix + $sta == $cursor
|
495
|
+
# f = f.ljust(wid)
|
496
|
+
f << ' ' * (wid - fsz)
|
490
497
|
end
|
491
498
|
|
492
499
|
if buff[ctr]
|
@@ -495,156 +502,188 @@ def columnate ary, sz
|
|
495
502
|
buff[ctr] = f
|
496
503
|
end
|
497
504
|
|
498
|
-
ctr+=1
|
499
|
-
ix+=1
|
505
|
+
ctr += 1
|
506
|
+
ix += 1
|
500
507
|
break if ix >= ary.size
|
501
508
|
end
|
502
509
|
break if ix >= ary.size
|
503
510
|
end
|
504
|
-
|
511
|
+
buff
|
505
512
|
end
|
513
|
+
|
506
514
|
## formats the data with number, mark and details
|
507
|
-
|
508
|
-
|
515
|
+
# 2019-03-09 - at some time this got renamed to `format` which is a kernel
|
516
|
+
# method and this overshadowed that method.
|
517
|
+
def _format(ary)
|
518
|
+
# buff = Array.new
|
509
519
|
buff = Array.new(ary.size)
|
510
|
-
return buff if ary.nil? || ary.
|
520
|
+
return buff if ary.nil? || ary.empty?
|
511
521
|
|
512
522
|
# determine width based on number of files to show
|
513
523
|
# if less than sz then 1 col and full width
|
514
524
|
#
|
515
525
|
# ix refers to the index in the complete file list, wherease we only show 60 at a time
|
516
|
-
ix=0
|
517
|
-
ctr=0
|
526
|
+
ix = 0
|
527
|
+
ctr = 0
|
518
528
|
ary.each do |f|
|
519
529
|
## ctr refers to the index in the column
|
520
530
|
ind = get_shortcut(ix)
|
521
|
-
mark=SPACE
|
522
|
-
cur=SPACE
|
531
|
+
mark = SPACE
|
532
|
+
cur = SPACE
|
523
533
|
cur = CURMARK if ix + $sta == $cursor
|
524
|
-
|
534
|
+
# TODO: add full path TESTME
|
535
|
+
# mark = GMARK if $selected_files.index(ary[ix])
|
536
|
+
mark = GMARK if selected?(ary[ix])
|
525
537
|
|
526
538
|
if $long_listing
|
527
539
|
begin
|
528
|
-
|
529
|
-
last = f[-1]
|
530
|
-
if last == " " || last == "@" || last == '*'
|
531
|
-
stat = File.stat(f.chop)
|
532
|
-
end
|
533
|
-
else
|
540
|
+
if File.exist? f
|
534
541
|
stat = File.stat(f)
|
542
|
+
else
|
543
|
+
last = f[-1]
|
544
|
+
stat = File.stat(f.chop) if last == ' ' || last == '@' || last == '*'
|
535
545
|
end
|
536
|
-
f =
|
546
|
+
f = format('%10s %s %s', readable_file_size(stat.size, 1),
|
547
|
+
date_format(stat.mtime), f)
|
537
548
|
rescue Exception => e
|
538
|
-
f =
|
549
|
+
f = format('%10s %s %s', '?', '??????????', f)
|
539
550
|
end
|
540
551
|
end
|
541
552
|
|
542
553
|
s = "#{ind}#{mark}#{cur}#{f}"
|
543
554
|
# I cannot color the current line since format does the chopping
|
544
|
-
# so not only does the next lines alignment get
|
555
|
+
# so not only does the next lines alignment get skewed,
|
556
|
+
# but also if the line is truncated
|
545
557
|
# then the color overflows.
|
546
|
-
#if ix + $sta == $cursor
|
547
|
-
|
548
|
-
#end
|
558
|
+
# if ix + $sta == $cursor
|
559
|
+
# s = "#{RED}#{s}#{CLEAR}"
|
560
|
+
# end
|
549
561
|
|
550
562
|
buff[ctr] = s
|
551
563
|
|
552
|
-
ctr+=1
|
553
|
-
ix+=1
|
564
|
+
ctr += 1
|
565
|
+
ix += 1
|
554
566
|
end
|
555
|
-
|
567
|
+
buff
|
556
568
|
end
|
569
|
+
|
557
570
|
## select file based on key pressed
|
558
|
-
def select_hint
|
571
|
+
def select_hint(view, ch)
|
559
572
|
# a to y is direct
|
560
573
|
# if x or z take a key IF there are those many
|
561
574
|
#
|
562
575
|
ix = get_index(ch, view.size)
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
+
return unless ix
|
577
|
+
|
578
|
+
f = view[ix]
|
579
|
+
return unless f
|
580
|
+
|
581
|
+
$cursor = $sta + ix
|
582
|
+
|
583
|
+
if $mode == 'SEL'
|
584
|
+
toggle_select f
|
585
|
+
elsif $mode == 'COM'
|
586
|
+
run_command f
|
587
|
+
else
|
588
|
+
open_file f
|
576
589
|
end
|
590
|
+
# selectedix=ix
|
577
591
|
end
|
592
|
+
|
578
593
|
## toggle selection state of file
|
579
|
-
def toggle_select
|
580
|
-
|
581
|
-
|
594
|
+
def toggle_select(f)
|
595
|
+
# dir = Dir.pwd
|
596
|
+
# file = File.join(dir, f)
|
597
|
+
if selected? f
|
598
|
+
remove_from_selection f
|
582
599
|
else
|
583
|
-
|
600
|
+
add_to_selection f
|
584
601
|
end
|
585
602
|
end
|
586
603
|
|
587
604
|
## open file or directory
|
588
|
-
def open_file
|
605
|
+
def open_file(f)
|
589
606
|
return unless f
|
590
|
-
|
591
|
-
|
592
|
-
end
|
607
|
+
|
608
|
+
f = File.expand_path(f) if f[0] == '~'
|
593
609
|
unless File.exist? f
|
594
610
|
# this happens if we use (T) in place of (M)
|
595
611
|
# it places a space after normal files and @ and * which borks commands
|
596
612
|
last = f[-1]
|
597
|
-
if last ==
|
598
|
-
f = f.chop
|
599
|
-
end
|
613
|
+
f = f.chop if last == ' ' || last == '@' || last == '*'
|
600
614
|
end
|
601
615
|
nextpos = nil
|
602
616
|
|
603
617
|
# could be a bookmark with position attached to it
|
604
|
-
if f.index(
|
605
|
-
f, nextpos = f.split(":")
|
606
|
-
end
|
618
|
+
f, nextpos = f.split(':') if f.index(':')
|
607
619
|
if File.directory? f
|
608
620
|
save_dir_pos
|
609
621
|
change_dir f, nextpos
|
610
622
|
elsif File.readable? f
|
611
|
-
$default_command ||=
|
623
|
+
$default_command ||= '$PAGER'
|
612
624
|
if !$editor_mode
|
613
625
|
ft = filetype f
|
614
626
|
if ft
|
615
627
|
comm = $pager_command[ft]
|
616
628
|
else
|
617
629
|
comm = $pager_command[File.extname(f)]
|
618
|
-
comm
|
630
|
+
comm ||= $pager_command['unknown']
|
619
631
|
end
|
620
632
|
else
|
621
633
|
comm = $default_command
|
622
634
|
end
|
623
635
|
comm ||= $default_command
|
624
|
-
if comm.index(
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
636
|
+
comm = if comm.index('%%')
|
637
|
+
comm.gsub('%%', Shellwords.escape(f))
|
638
|
+
else
|
639
|
+
comm + " #{Shellwords.escape(f)}"
|
640
|
+
end
|
629
641
|
clear_screen
|
630
642
|
reset_terminal
|
631
|
-
system(
|
643
|
+
system(comm.to_s)
|
632
644
|
setup_terminal
|
633
|
-
f = Dir.pwd +
|
645
|
+
f = Dir.pwd + '/' + f if f[0] != '/'
|
634
646
|
$visited_files.insert(0, f)
|
635
647
|
push_used_dirs Dir.pwd
|
636
648
|
else
|
637
649
|
perror "open_file: (#{f}) not found"
|
638
|
-
|
650
|
+
# could check home dir or CDPATH env variable DO
|
639
651
|
end
|
640
652
|
end
|
641
653
|
|
654
|
+
# regardless of mode, view the current file using pager
|
655
|
+
def page_current
|
656
|
+
command = ENV['MANPAGER'] || ENV['PAGER'] || 'less'
|
657
|
+
run_on_current command
|
658
|
+
end
|
659
|
+
|
660
|
+
# regardless of mode, edit the current file using editor
|
661
|
+
def edit_current
|
662
|
+
command = ENV['EDITOR'] || ENV['VISUAL'] || 'vim'
|
663
|
+
run_on_current command
|
664
|
+
$visited_files.insert(0, current_file)
|
665
|
+
end
|
666
|
+
|
667
|
+
# run given command on current file
|
668
|
+
def run_on_current(command)
|
669
|
+
f = $view[$cursor]
|
670
|
+
return unless f
|
671
|
+
f = File.expand_path(f)
|
672
|
+
return unless File.readable?(f)
|
673
|
+
|
674
|
+
clear_screen
|
675
|
+
reset_terminal
|
676
|
+
comm = "#{command} #{f}"
|
677
|
+
system(comm.to_s)
|
678
|
+
setup_terminal
|
679
|
+
end
|
680
|
+
|
642
681
|
## run command on given file/s
|
643
682
|
# Accepts command from user
|
644
683
|
# After putting readline in place of gets, pressing a C-c has a delayed effect. It goes intot
|
645
684
|
# exception bloack after executing other commands and still does not do the return !
|
646
|
-
def run_command
|
647
|
-
files=nil
|
685
|
+
def run_command(f)
|
686
|
+
files = nil
|
648
687
|
case f
|
649
688
|
when Array
|
650
689
|
# escape the contents and create a string
|
@@ -654,13 +693,14 @@ def run_command f
|
|
654
693
|
end
|
655
694
|
print "Run a command on #{files}: "
|
656
695
|
begin
|
657
|
-
#Readline::HISTORY.push(*values)
|
658
|
-
command = Readline
|
659
|
-
#command = gets().chomp
|
660
|
-
return if command.
|
661
|
-
|
662
|
-
|
663
|
-
command2 =
|
696
|
+
# Readline::HISTORY.push(*values)
|
697
|
+
command = Readline.readline('>', true)
|
698
|
+
# command = gets().chomp
|
699
|
+
return if command.empty?
|
700
|
+
|
701
|
+
print 'Second part of command: '
|
702
|
+
# command2 = gets().chomp
|
703
|
+
command2 = Readline.readline('>', true)
|
664
704
|
puts "#{command} #{files} #{command2}"
|
665
705
|
system "#{command} #{files} #{command2}"
|
666
706
|
rescue Exception => ex
|
@@ -672,27 +712,33 @@ def run_command f
|
|
672
712
|
end
|
673
713
|
|
674
714
|
refresh
|
675
|
-
puts
|
715
|
+
puts 'Press a key ...'
|
676
716
|
push_used_dirs Dir.pwd
|
677
717
|
get_char
|
678
718
|
end
|
679
719
|
|
680
720
|
## cd to a dir
|
681
|
-
def change_dir
|
721
|
+
def change_dir(f, pos = nil)
|
682
722
|
$visited_dirs.insert(0, Dir.pwd)
|
683
723
|
f = File.expand_path(f)
|
684
724
|
Dir.chdir f
|
685
|
-
$filterstr ||=
|
725
|
+
$filterstr ||= 'M'
|
686
726
|
$files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}#{$filterstr})'`.split("\n")
|
687
727
|
$files = sort_file_list $files
|
688
728
|
post_cd
|
689
729
|
if pos
|
690
730
|
# convert curpos to sta also
|
691
|
-
|
731
|
+
# $cursor = pos.to_i
|
692
732
|
goto_line pos.to_i
|
693
733
|
end
|
694
734
|
end
|
695
735
|
|
736
|
+
def goto_previous_dir
|
737
|
+
prev_dir = $visited_dirs.first
|
738
|
+
return unless prev_dir
|
739
|
+
change_dir prev_dir
|
740
|
+
end
|
741
|
+
|
696
742
|
## clear sort order and refresh listing, used typically if you are in some view
|
697
743
|
# such as visited dirs or files
|
698
744
|
def escape
|
@@ -700,25 +746,25 @@ def escape
|
|
700
746
|
$sorto = $default_sort_order
|
701
747
|
$viewctr = 0
|
702
748
|
$title = nil
|
703
|
-
$filterstr =
|
749
|
+
$filterstr = 'M'
|
704
750
|
visual_block_clear
|
705
751
|
refresh
|
706
752
|
end
|
707
753
|
|
708
754
|
## refresh listing after some change like option change, or toggle
|
709
755
|
def refresh
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
756
|
+
$filterstr ||= 'M'
|
757
|
+
$files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}#{$filterstr})'`.split("\n")
|
758
|
+
# first put dirs then files
|
759
|
+
$files = sort_file_list $files
|
760
|
+
$patt = nil
|
761
|
+
$title = nil
|
716
762
|
end
|
717
763
|
|
718
|
-
def sort_file_list
|
719
|
-
|
720
|
-
|
721
|
-
|
764
|
+
def sort_file_list(_files)
|
765
|
+
_dirs = $files.select { |f| File.directory?(f) }
|
766
|
+
_files = $files.select { |f| File.file?(f) }
|
767
|
+
_dirs + _files
|
722
768
|
end
|
723
769
|
|
724
770
|
## unselect all files
|
@@ -729,31 +775,31 @@ end
|
|
729
775
|
|
730
776
|
## select all files
|
731
777
|
def select_all
|
732
|
-
|
778
|
+
# TODO: add path TESTME
|
779
|
+
dir = Dir.pwd
|
780
|
+
$selected_files = $view.map { |file| File.join(dir, file) }
|
733
781
|
end
|
734
782
|
|
735
783
|
## accept dir to goto and change to that ( can be a file too)
|
736
784
|
def goto_dir
|
737
|
-
print
|
785
|
+
print 'Enter path: '
|
738
786
|
begin
|
739
|
-
#path = gets.chomp
|
740
|
-
path = Readline
|
741
|
-
return if path ==
|
742
|
-
#rescue => ex
|
787
|
+
# path = gets.chomp
|
788
|
+
path = Readline.readline('>', true)
|
789
|
+
return if path == ''
|
790
|
+
# rescue => ex
|
743
791
|
rescue Exception => ex
|
744
|
-
perror
|
792
|
+
perror 'Cancelled cd, press a key'
|
745
793
|
return
|
746
794
|
end
|
747
795
|
f = File.expand_path(path)
|
748
796
|
unless File.directory? f
|
749
797
|
## check for env variable
|
750
798
|
tmp = ENV[path]
|
751
|
-
if tmp.nil? || !File.directory?(
|
799
|
+
if tmp.nil? || !File.directory?(tmp)
|
752
800
|
## check for dir in home
|
753
801
|
tmp = File.expand_path("~/#{path}")
|
754
|
-
if File.directory? tmp
|
755
|
-
f = tmp
|
756
|
-
end
|
802
|
+
f = tmp if File.directory? tmp
|
757
803
|
else
|
758
804
|
f = tmp
|
759
805
|
end
|
@@ -769,15 +815,14 @@ end
|
|
769
815
|
def selection_mode_toggle
|
770
816
|
if $mode == 'SEL'
|
771
817
|
# we seem to be coming out of select mode with some files
|
772
|
-
|
773
|
-
run_command $selected_files
|
774
|
-
end
|
818
|
+
run_command $selected_files unless $selected_files.empty?
|
775
819
|
$mode = nil
|
776
820
|
else
|
777
|
-
|
821
|
+
# $selection_mode = !$selection_mode
|
778
822
|
$mode = 'SEL'
|
779
823
|
end
|
780
824
|
end
|
825
|
+
|
781
826
|
## toggle command mode
|
782
827
|
def command_mode
|
783
828
|
if $mode == 'COM'
|
@@ -786,24 +831,32 @@ def command_mode
|
|
786
831
|
end
|
787
832
|
$mode = 'COM'
|
788
833
|
end
|
834
|
+
|
789
835
|
def goto_parent_dir
|
790
836
|
change_dir '..'
|
791
837
|
end
|
838
|
+
|
839
|
+
def goto_home_dir
|
840
|
+
change_dir '~'
|
841
|
+
end
|
842
|
+
|
792
843
|
## This actually filters, in zfm it goes to that entry since we have a cursor there
|
793
844
|
#
|
794
|
-
def goto_entry_starting_with
|
845
|
+
def goto_entry_starting_with(fc = nil)
|
795
846
|
unless fc
|
796
|
-
print
|
847
|
+
print 'Entries starting with: '
|
797
848
|
fc = get_char
|
798
849
|
end
|
799
850
|
return if fc.size != 1
|
851
|
+
|
800
852
|
## this is wrong and duplicates the functionality of /
|
801
853
|
# It shoud go to cursor of item starting with fc
|
802
854
|
$patt = "^#{fc}"
|
803
855
|
end
|
804
|
-
|
856
|
+
|
857
|
+
def goto_bookmark(ch = nil)
|
805
858
|
unless ch
|
806
|
-
print
|
859
|
+
print 'Enter bookmark char: '
|
807
860
|
ch = get_char
|
808
861
|
end
|
809
862
|
if ch =~ /^[0-9A-Z]$/
|
@@ -812,122 +865,173 @@ def goto_bookmark ch=nil
|
|
812
865
|
# this way we leave the position as is, so it gets written back
|
813
866
|
nextpos = nil
|
814
867
|
if d
|
815
|
-
if d.index(
|
816
|
-
ix = d.index(
|
817
|
-
nextpos = d[ix+1..-1]
|
818
|
-
d = d[0,ix]
|
868
|
+
if d.index(':')
|
869
|
+
ix = d.index(':')
|
870
|
+
nextpos = d[ix + 1..-1]
|
871
|
+
d = d[0, ix]
|
819
872
|
end
|
820
873
|
change_dir d, nextpos
|
821
874
|
else
|
822
875
|
perror "#{ch} not a bookmark"
|
823
876
|
end
|
824
877
|
else
|
825
|
-
#goto_entry_starting_with ch
|
878
|
+
# goto_entry_starting_with ch
|
826
879
|
file_starting_with ch
|
827
880
|
end
|
828
881
|
end
|
829
882
|
|
830
|
-
|
831
883
|
## take regex from user, to run on files on screen, user can filter file names
|
832
884
|
def enter_regex
|
833
|
-
print
|
834
|
-
|
835
|
-
$patt = Readline
|
885
|
+
print 'Enter (regex) pattern: '
|
886
|
+
# $patt = gets().chomp
|
887
|
+
$patt = Readline.readline('>', true)
|
836
888
|
ctr = 0
|
837
889
|
end
|
890
|
+
|
838
891
|
def next_page
|
839
892
|
$sta += $pagesize
|
840
893
|
end
|
894
|
+
|
841
895
|
def prev_page
|
842
896
|
$sta -= $pagesize
|
843
897
|
end
|
844
898
|
|
899
|
+
# print help on key-bindings
|
900
|
+
# 2019-03-08 - write to temp file and user PAGER
|
845
901
|
def print_help
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
902
|
+
require 'tempfile'
|
903
|
+
file = Tempfile.new('help')
|
904
|
+
begin
|
905
|
+
file.puts ' HELP'
|
906
|
+
|
907
|
+
file.puts
|
908
|
+
file.puts 'To open a file or dir press 1-9 a-z A-Z '
|
909
|
+
file.puts 'Command Mode: Will prompt for a command to run on a file, after selecting using hotkey'
|
910
|
+
file.puts 'Selection Mode: Each selection adds to selection list (toggles)'
|
911
|
+
file.puts ' Execute commands on selected files. e.g D '
|
912
|
+
file.puts ' Upon exiting mode, user is prompted for a command to run on selected files'
|
913
|
+
file.puts
|
914
|
+
ary = []
|
915
|
+
$bindings.each_pair { |k, v| ary.push "#{k.ljust(7)} => #{v}" }
|
916
|
+
ary = columnate ary, (ary.size/2)+1
|
917
|
+
ary.each { |line| file.puts line }
|
918
|
+
file.flush
|
919
|
+
system "$PAGER #{file.path}"
|
920
|
+
rescue
|
921
|
+
file.close
|
922
|
+
file.unlink
|
923
|
+
end
|
924
|
+
end #
|
859
925
|
|
860
|
-
end
|
861
926
|
def show_marks
|
862
927
|
puts
|
863
|
-
puts
|
928
|
+
puts 'Bookmarks: '
|
864
929
|
$bookmarks.each_pair { |k, v| puts "#{k.ljust(7)} => #{v}" }
|
865
930
|
puts
|
866
|
-
print
|
931
|
+
print 'Enter bookmark to goto: '
|
867
932
|
ch = get_char
|
868
933
|
goto_bookmark(ch) if ch =~ /^[0-9A-Z]$/
|
869
934
|
end
|
935
|
+
|
870
936
|
# MENU MAIN -- keep consistent with zfm
|
871
937
|
def main_menu
|
872
938
|
h = {
|
873
|
-
:a => :
|
874
|
-
|
939
|
+
:a => :ag,
|
940
|
+
'/' => :ffind,
|
875
941
|
:l => :locate,
|
876
|
-
:
|
942
|
+
:V => :viminfo,
|
943
|
+
:v => :vidir,
|
877
944
|
:z => :z_interface,
|
878
945
|
:d => :child_dirs,
|
879
946
|
:r => :recent_files,
|
947
|
+
'1' => :select_visited_files,
|
948
|
+
'2' => :select_used_dirs,
|
880
949
|
:t => :dirtree,
|
881
|
-
|
950
|
+
'4' => :tree,
|
882
951
|
:s => :sort_menu,
|
883
952
|
:F => :filter_menu,
|
884
|
-
:c => :command_menu
|
953
|
+
:c => :command_menu,
|
885
954
|
:B => :bindkey_ext_command,
|
886
955
|
:M => :newdir,
|
887
|
-
|
956
|
+
'%' => :newfile,
|
957
|
+
'S' => :scripts,
|
888
958
|
:x => :extras
|
889
959
|
}
|
890
|
-
menu
|
960
|
+
menu 'Main Menu', h
|
961
|
+
end
|
962
|
+
|
963
|
+
# trying out fzf instead
|
964
|
+
# 2019-03-08 - 23:46
|
965
|
+
# FIXME returns a String not symbol, so some callers can fail
|
966
|
+
def fzfmenu(title, h)
|
967
|
+
return unless h
|
968
|
+
|
969
|
+
pbold title.to_s
|
970
|
+
values = h.values.join("\n")
|
971
|
+
binding = `echo "#{values}" | fzf --prompt="#{title.to_s} :"`
|
972
|
+
# h.each_pair { |k, v| puts " #{k}: #{v}" }
|
973
|
+
# ch = get_char
|
974
|
+
# binding = h[ch]
|
975
|
+
# binding ||= h[ch.to_sym]
|
976
|
+
# FIXME we have converted symbol to string
|
977
|
+
ch = nil
|
978
|
+
if binding
|
979
|
+
binding = binding.chomp
|
980
|
+
send(binding) if respond_to?(binding, true)
|
981
|
+
ch = h.key(binding)
|
982
|
+
end
|
983
|
+
[ch, binding]
|
891
984
|
end
|
892
|
-
|
985
|
+
|
986
|
+
# this style used hotkeys which I remember. But it can get long.
|
987
|
+
# and I have to fix a hotkey for each new entry
|
988
|
+
def menu(title, h)
|
893
989
|
return unless h
|
894
990
|
|
895
|
-
pbold
|
896
|
-
h.each_pair { |k, v| puts " #{k}: #{v}" }
|
991
|
+
pbold title.to_s
|
992
|
+
# h.each_pair { |k, v| puts " #{k}: #{v}" }
|
993
|
+
# 2019-03-09 - trying out using `column` to print in cols
|
994
|
+
ary = []
|
995
|
+
h.each_pair { |k, v| ary << " #{k}: #{v}" }
|
996
|
+
x = ary.join("\n")
|
997
|
+
puts %x{echo "#{x}" | column}
|
998
|
+
|
897
999
|
ch = get_char
|
898
1000
|
binding = h[ch]
|
899
|
-
binding
|
1001
|
+
binding ||= h[ch.to_sym]
|
900
1002
|
if binding
|
901
|
-
if respond_to?(binding, true)
|
902
|
-
send(binding)
|
903
|
-
end
|
1003
|
+
send(binding) if respond_to?(binding, true)
|
904
1004
|
end
|
905
|
-
|
1005
|
+
[ch, binding]
|
906
1006
|
end
|
1007
|
+
|
907
1008
|
def toggle_menu
|
908
|
-
h = { :h => :toggle_hidden, :c => :toggle_case, :l => :toggle_long_list
|
909
|
-
|
910
|
-
ch, menu_text = menu
|
1009
|
+
h = { :h => :toggle_hidden, :c => :toggle_case, :l => :toggle_long_list, '1' => :toggle_columns,
|
1010
|
+
:p => :toggle_pager_mode, :e => :toggle_enhanced_list }
|
1011
|
+
ch, menu_text = menu 'Toggle Menu', h
|
1012
|
+
# NOTE fzfmenu returns string not symbol
|
1013
|
+
return unless menu_text
|
1014
|
+
|
911
1015
|
case menu_text
|
912
1016
|
when :toggle_hidden
|
913
|
-
$hidden = $hidden ? nil :
|
1017
|
+
$hidden = $hidden ? nil : 'D'
|
914
1018
|
refresh
|
915
1019
|
when :toggle_case
|
916
|
-
|
1020
|
+
# $ignorecase = $ignorecase ? "" : "i"
|
917
1021
|
$ignorecase = !$ignorecase
|
918
1022
|
refresh
|
919
1023
|
when :toggle_columns
|
920
1024
|
$gviscols = 3 if $gviscols == 1
|
921
|
-
|
1025
|
+
# $long_listing = false if $gviscols > 1
|
922
1026
|
x = $grows * $gviscols
|
923
|
-
$pagesize = $pagesize==x ? $grows : x
|
1027
|
+
$pagesize = $pagesize == x ? $grows : x
|
924
1028
|
when :toggle_pager_mode
|
925
1029
|
$editor_mode = !$editor_mode
|
926
|
-
if $editor_mode
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
1030
|
+
$default_command = if $editor_mode
|
1031
|
+
ENV['EDITOR'] # earlier nil # 2019-03-10 -
|
1032
|
+
else
|
1033
|
+
ENV['MANPAGER'] || ENV['PAGER']
|
1034
|
+
end
|
931
1035
|
when :toggle_enhanced_list
|
932
1036
|
$enhanced_mode = !$enhanced_mode
|
933
1037
|
|
@@ -938,7 +1042,7 @@ def toggle_menu
|
|
938
1042
|
$pagesize = $grows
|
939
1043
|
else
|
940
1044
|
x = $grows * $gviscols
|
941
|
-
$pagesize = $pagesize==x ? $grows : x
|
1045
|
+
$pagesize = $pagesize == x ? $grows : x
|
942
1046
|
end
|
943
1047
|
refresh
|
944
1048
|
end
|
@@ -946,34 +1050,34 @@ end
|
|
946
1050
|
|
947
1051
|
def sort_menu
|
948
1052
|
lo = nil
|
949
|
-
h = { :
|
950
|
-
|
951
|
-
ch, menu_text = menu
|
1053
|
+
h = { n: :newest, a: :accessed, o: :oldest,
|
1054
|
+
l: :largest, s: :smallest, m: :name, r: :rname, d: :dirs, c: :clear }
|
1055
|
+
ch, menu_text = menu 'Sort Menu', h
|
952
1056
|
case menu_text
|
953
1057
|
when :newest
|
954
|
-
lo=
|
1058
|
+
lo = 'om'
|
955
1059
|
when :accessed
|
956
|
-
lo=
|
1060
|
+
lo = 'oa'
|
957
1061
|
when :oldest
|
958
|
-
lo=
|
1062
|
+
lo = 'Om'
|
959
1063
|
when :largest
|
960
|
-
lo=
|
1064
|
+
lo = 'OL'
|
961
1065
|
when :smallest
|
962
|
-
lo=
|
1066
|
+
lo = 'oL'
|
963
1067
|
when :name
|
964
|
-
lo=
|
1068
|
+
lo = 'on'
|
965
1069
|
when :rname
|
966
|
-
lo=
|
1070
|
+
lo = 'On'
|
967
1071
|
when :dirs
|
968
|
-
lo=
|
1072
|
+
lo = '/'
|
969
1073
|
when :clear
|
970
|
-
lo=
|
1074
|
+
lo = ''
|
971
1075
|
end
|
972
1076
|
## This needs to persist and be a part of all listings, put in change_dir.
|
973
1077
|
$sorto = lo
|
974
1078
|
$files = `zsh -c 'print -rl -- *(#{lo}#{$hidden}M)'`.split("\n") if lo
|
975
1079
|
$title = nil
|
976
|
-
|
1080
|
+
# $files =$(eval "print -rl -- ${pattern}(${MFM_LISTORDER}$filterstr)")
|
977
1081
|
end
|
978
1082
|
|
979
1083
|
def command_menu
|
@@ -986,13 +1090,14 @@ def command_menu
|
|
986
1090
|
# should be able to sort THIS listing and not rerun command. But for that I'd need to use
|
987
1091
|
# xargs ls -t etc rather than the zsh sort order. But we can run a filter using |.
|
988
1092
|
#
|
989
|
-
h = { :
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
1093
|
+
h = { t: :today, D: :default_command, R: :remove_from_list,
|
1094
|
+
v: :page_selection }
|
1095
|
+
h[:e] = if $editor_mode
|
1096
|
+
:pager_mode
|
1097
|
+
else
|
1098
|
+
:editor_mode
|
1099
|
+
end
|
1100
|
+
_, menu_text = menu 'Command Menu', h
|
996
1101
|
case menu_text
|
997
1102
|
when :pager_mode
|
998
1103
|
$editor_mode = false
|
@@ -1008,26 +1113,27 @@ def command_menu
|
|
1008
1113
|
$files = `zsh -c 'print -rl -- *(#{$hidden}Mm0)'`.split("\n")
|
1009
1114
|
$title = "Today's files"
|
1010
1115
|
when :default_command
|
1011
|
-
print
|
1012
|
-
$default_command = gets
|
1013
|
-
if $default_command !=
|
1014
|
-
print
|
1015
|
-
$default_command2 = gets
|
1116
|
+
print 'Selecting a file usually invokes $EDITOR, what command do you want to use repeatedly on selected files: '
|
1117
|
+
$default_command = gets.chomp
|
1118
|
+
if $default_command != ''
|
1119
|
+
print 'Second part of command (maybe blank): '
|
1120
|
+
$default_command2 = gets.chomp
|
1016
1121
|
else
|
1017
|
-
print
|
1122
|
+
print 'Cleared default command, will default to $EDITOR'
|
1018
1123
|
$default_command2 = nil
|
1019
1124
|
$default_command = nil
|
1020
1125
|
end
|
1021
1126
|
end
|
1022
1127
|
end
|
1128
|
+
|
1023
1129
|
def extras
|
1024
|
-
h = {
|
1025
|
-
ch, menu_text = menu
|
1130
|
+
h = { '1' => :one_column, '2' => :multi_column, :c => :columns, :r => :config_read, :w => :config_write }
|
1131
|
+
ch, menu_text = menu 'Extras Menu', h
|
1026
1132
|
case menu_text
|
1027
1133
|
when :one_column
|
1028
1134
|
$pagesize = $grows
|
1029
1135
|
when :multi_column
|
1030
|
-
|
1136
|
+
# $pagesize = 60
|
1031
1137
|
$pagesize = $grows * $gviscols
|
1032
1138
|
when :columns
|
1033
1139
|
print "How many columns to show: 1-6 [current #{$gviscols}]? "
|
@@ -1039,44 +1145,50 @@ def extras
|
|
1039
1145
|
end
|
1040
1146
|
end
|
1041
1147
|
end
|
1148
|
+
|
1042
1149
|
def filter_menu
|
1043
|
-
h = { :d => :dirs, :f => :files, :e => :emptydirs
|
1044
|
-
ch, menu_text = menu
|
1150
|
+
h = { :d => :dirs, :f => :files, :e => :emptydirs, '0' => :emptyfiles }
|
1151
|
+
ch, menu_text = menu 'Filter Menu', h
|
1045
1152
|
files = nil
|
1046
1153
|
case menu_text
|
1047
1154
|
when :dirs
|
1048
|
-
$filterstr =
|
1155
|
+
$filterstr = '/M'
|
1049
1156
|
files = `zsh -c 'print -rl -- *(#{$sorto}/M)'`.split("\n")
|
1050
|
-
$title =
|
1157
|
+
$title = 'Filter: directories only'
|
1051
1158
|
when :files
|
1052
|
-
$filterstr =
|
1159
|
+
$filterstr = '.'
|
1053
1160
|
files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}.)'`.split("\n")
|
1054
|
-
$title =
|
1161
|
+
$title = 'Filter: files only'
|
1055
1162
|
when :emptydirs
|
1056
|
-
$filterstr =
|
1163
|
+
$filterstr = '/D^F'
|
1057
1164
|
files = `zsh -c 'print -rl -- *(#{$sorto}/D^F)'`.split("\n")
|
1058
|
-
$title =
|
1165
|
+
$title = 'Filter: empty directories'
|
1059
1166
|
when :emptyfiles
|
1060
|
-
$filterstr =
|
1167
|
+
$filterstr = '.L0'
|
1061
1168
|
files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}.L0)'`.split("\n")
|
1062
|
-
$title =
|
1169
|
+
$title = 'Filter: empty files'
|
1063
1170
|
end
|
1064
1171
|
if files
|
1065
1172
|
$files = files
|
1066
1173
|
$stact = 0
|
1067
1174
|
end
|
1068
1175
|
end
|
1176
|
+
|
1069
1177
|
def select_used_dirs
|
1070
|
-
$title =
|
1071
|
-
|
1178
|
+
$title = 'Used Directories'
|
1179
|
+
home = File.expand_path '~'
|
1180
|
+
$files = $used_dirs.uniq.map { |path| path.sub("#{home}", '~') }
|
1072
1181
|
end
|
1182
|
+
|
1073
1183
|
def select_visited_files
|
1074
1184
|
# not yet a unique list, needs to be unique and have latest pushed to top
|
1075
|
-
$title =
|
1076
|
-
|
1185
|
+
$title = 'Visited Files'
|
1186
|
+
home = File.expand_path '~'
|
1187
|
+
$files = $visited_files.uniq.map { |path| path.sub("#{home}", '~') }
|
1077
1188
|
end
|
1189
|
+
|
1078
1190
|
def select_bookmarks
|
1079
|
-
$title =
|
1191
|
+
$title = 'Bookmarks'
|
1080
1192
|
$files = $bookmarks.values
|
1081
1193
|
end
|
1082
1194
|
|
@@ -1084,15 +1196,13 @@ end
|
|
1084
1196
|
# or we'll be stuck in a cycle
|
1085
1197
|
def pop_dir
|
1086
1198
|
# the first time we pop, we need to put the current on stack
|
1087
|
-
|
1088
|
-
$visited_dirs.push Dir.pwd
|
1089
|
-
end
|
1199
|
+
$visited_dirs.push Dir.pwd unless $visited_dirs.index(Dir.pwd)
|
1090
1200
|
## XXX make sure thre is something to pop
|
1091
1201
|
d = $visited_dirs.delete_at 0
|
1092
1202
|
## XXX make sure the dir exists, cuold have been deleted. can be an error or crash otherwise
|
1093
1203
|
$visited_dirs.push d
|
1094
1204
|
Dir.chdir d
|
1095
|
-
$filterstr ||=
|
1205
|
+
$filterstr ||= 'M'
|
1096
1206
|
$files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}#{$filterstr})'`.split("\n")
|
1097
1207
|
$files = sort_file_list $files
|
1098
1208
|
post_cd
|
@@ -1100,14 +1210,14 @@ end
|
|
1100
1210
|
|
1101
1211
|
# after changing directory
|
1102
1212
|
def post_cd
|
1103
|
-
$patt=nil
|
1213
|
+
$patt = nil
|
1104
1214
|
$sta = $cursor = 0
|
1105
1215
|
$title = nil
|
1106
|
-
|
1107
|
-
|
1108
|
-
end
|
1216
|
+
# 2019-03-10 - why am I clearing selected when dir changed !!! FIXME
|
1217
|
+
# $selected_files = [] unless $selected_files.empty?
|
1109
1218
|
$visual_block_start = nil
|
1110
1219
|
$stact = 0
|
1220
|
+
$current_dir = Dir.pwd # 2019-03-10 - so i don't keep doing in functions
|
1111
1221
|
screen_settings
|
1112
1222
|
# i think this will screw with the dir_pos since it is not filename based.
|
1113
1223
|
enhance_file_list
|
@@ -1118,103 +1228,108 @@ end
|
|
1118
1228
|
|
1119
1229
|
## read dirs and files and bookmarks from file
|
1120
1230
|
def config_read
|
1121
|
-
#f = File.expand_path("~/.zfminfo")
|
1122
|
-
f =
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
chars = ('A'..'Z').to_a
|
1131
|
-
chars.concat( ('0'..'9').to_a )
|
1132
|
-
chars.each do |ch|
|
1133
|
-
if Kernel.const_defined? "BM_#{ch}"
|
1134
|
-
$bookmarks[ch] = Kernel.const_get "BM_#{ch}"
|
1135
|
-
end
|
1136
|
-
end
|
1137
|
-
end
|
1231
|
+
# f = File.expand_path("~/.zfminfo")
|
1232
|
+
f = File.expand_path(CONFIG_FILE)
|
1233
|
+
return unless File.readable? f
|
1234
|
+
|
1235
|
+
hash = loadYML(f)
|
1236
|
+
$used_dirs = hash['DIRS']
|
1237
|
+
$visited_files = hash['FILES']
|
1238
|
+
$bookmarks = hash['BOOKMARKS']
|
1239
|
+
$used_dirs.concat get_env_paths
|
1138
1240
|
end
|
1241
|
+
|
1139
1242
|
def get_env_paths
|
1140
1243
|
files = []
|
1141
|
-
%w
|
1244
|
+
%w[GEM_HOME PYTHONHOME].each do |p|
|
1142
1245
|
d = ENV[p]
|
1143
1246
|
files.push d if d
|
1144
1247
|
end
|
1145
|
-
%w
|
1248
|
+
%w[RUBYLIB RUBYPATH GEM_PATH PYTHONPATH].each do |p|
|
1146
1249
|
d = ENV[p]
|
1147
|
-
files.concat d.split(
|
1250
|
+
files.concat d.split(':') if d
|
1148
1251
|
end
|
1149
|
-
|
1252
|
+
files
|
1150
1253
|
end
|
1151
1254
|
|
1152
1255
|
## save dirs and files and bookmarks to a file
|
1256
|
+
# - moved to yml 2019-03-09
|
1153
1257
|
def config_write
|
1154
1258
|
# Putting it in a format that zfm can also read and write
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
f2.puts "DIRS=\"#{d}\""
|
1162
|
-
f2.puts "FILES=\"#{f}\""
|
1163
|
-
$bookmarks.each_pair { |k, val|
|
1164
|
-
f2.puts "BM_#{k}=\"#{val}\""
|
1165
|
-
#f2.puts "BOOKMARKS[\"#{k}\"]=\"#{val}\""
|
1166
|
-
}
|
1167
|
-
end
|
1259
|
+
f1 = File.expand_path(CONFIG_FILE)
|
1260
|
+
hash = {}
|
1261
|
+
hash['DIRS'] = $used_dirs.select {|dir| File.exist? dir}
|
1262
|
+
hash['FILES'] = $visited_files.select {|file| File.exist? file}
|
1263
|
+
hash['BOOKMARKS'] = $bookmarks
|
1264
|
+
writeYML hash, f1
|
1168
1265
|
$writing = $modified = false
|
1169
1266
|
end
|
1170
1267
|
|
1268
|
+
# {{{ YML
|
1269
|
+
require 'yaml'
|
1270
|
+
def loadYML( filename)
|
1271
|
+
hash = YAML::load( File.open( filename ) )
|
1272
|
+
if $opt_debug
|
1273
|
+
$stderr.puts hash.keys.size
|
1274
|
+
end
|
1275
|
+
return hash
|
1276
|
+
end
|
1277
|
+
def writeYML obj, filename
|
1278
|
+
File.open(filename, 'w') {|f| f.write obj.to_yaml }
|
1279
|
+
if $opt_debug
|
1280
|
+
$stderr.puts "Written to file #{filename}"
|
1281
|
+
end
|
1282
|
+
end
|
1283
|
+
# }}}
|
1171
1284
|
## accept a character to save this dir as a bookmark
|
1172
1285
|
def create_bookmark
|
1173
|
-
print
|
1286
|
+
print 'Enter A to Z or 0-9 for bookmark: '
|
1174
1287
|
ch = get_char
|
1175
1288
|
if ch =~ /^[0-9A-Z]$/
|
1176
1289
|
$bookmarks[ch] = "#{Dir.pwd}:#{$cursor}"
|
1177
1290
|
$modified = true
|
1178
1291
|
else
|
1179
|
-
perror
|
1292
|
+
perror 'Bookmark must be upper-case character or number.'
|
1180
1293
|
end
|
1181
1294
|
end
|
1295
|
+
|
1182
1296
|
def subcommand
|
1183
|
-
print
|
1297
|
+
print 'Enter command: '
|
1184
1298
|
begin
|
1185
|
-
#command = gets().chomp
|
1186
|
-
command = Readline
|
1187
|
-
return if command ==
|
1299
|
+
# command = gets().chomp
|
1300
|
+
command = Readline.readline('>', true)
|
1301
|
+
return if command == ''
|
1188
1302
|
rescue Exception => ex
|
1189
1303
|
return
|
1190
1304
|
end
|
1191
|
-
if command ==
|
1305
|
+
if command == 'q'
|
1192
1306
|
if $modified
|
1193
|
-
print
|
1307
|
+
print 'Do you want to save bookmarks? (y/n): '
|
1194
1308
|
ch = get_char
|
1195
|
-
if ch ==
|
1309
|
+
if ch == 'y'
|
1196
1310
|
$writing = true
|
1197
1311
|
$quitting = true
|
1198
|
-
elsif ch ==
|
1312
|
+
elsif ch == 'n'
|
1199
1313
|
$quitting = true
|
1200
|
-
print
|
1314
|
+
print 'Quitting without saving bookmarks'
|
1201
1315
|
else
|
1202
|
-
perror
|
1316
|
+
perror 'No action taken.'
|
1203
1317
|
end
|
1204
1318
|
else
|
1205
1319
|
$quitting = true
|
1206
1320
|
end
|
1207
|
-
elsif command ==
|
1321
|
+
elsif command == 'wq'
|
1208
1322
|
$quitting = true
|
1209
1323
|
$writing = true
|
1210
|
-
elsif command ==
|
1324
|
+
elsif command == 'x'
|
1211
1325
|
$quitting = true
|
1212
1326
|
$writing = true if $modified
|
1213
|
-
elsif command ==
|
1327
|
+
elsif command == 'p'
|
1214
1328
|
system 'echo $PWD | pbcopy'
|
1215
1329
|
puts 'Stored PWD in clipboard (using pbcopy)'
|
1216
1330
|
end
|
1217
1331
|
end
|
1332
|
+
|
1218
1333
|
def quit_command
|
1219
1334
|
if $modified
|
1220
1335
|
puts 'Press w to save bookmarks before quitting ' if $modified
|
@@ -1228,91 +1343,102 @@ def quit_command
|
|
1228
1343
|
end
|
1229
1344
|
|
1230
1345
|
def views
|
1231
|
-
views
|
1232
|
-
viewlabels
|
1346
|
+
views = %w[/ om oa Om OL oL On on]
|
1347
|
+
viewlabels = %w[Dirs Newest Accessed Oldest Largest Smallest Reverse Name]
|
1233
1348
|
$sorto = views[$viewctr]
|
1234
1349
|
$title = viewlabels[$viewctr]
|
1235
1350
|
$viewctr += 1
|
1236
1351
|
$viewctr = 0 if $viewctr > views.size
|
1237
1352
|
|
1238
1353
|
$files = `zsh -c 'print -rl -- *(#{$sorto}#{$hidden}M)'`.split("\n")
|
1239
|
-
|
1240
1354
|
end
|
1355
|
+
|
1241
1356
|
def child_dirs
|
1242
|
-
$title =
|
1357
|
+
$title = 'Child directories'
|
1243
1358
|
$files = `zsh -c 'print -rl -- *(/#{$sorto}#{$hidden}M)'`.split("\n")
|
1244
1359
|
end
|
1360
|
+
|
1245
1361
|
def dirtree
|
1246
|
-
$title =
|
1362
|
+
$title = 'Child directories'
|
1247
1363
|
$files = `zsh -c 'print -rl -- **/*(/#{$sorto}#{$hidden}M)'`.split("\n")
|
1248
1364
|
end
|
1365
|
+
|
1249
1366
|
#
|
1250
1367
|
# Get a full recursive listing of what's in this dir - useful for small projects with more
|
1251
1368
|
# structure than files.
|
1252
1369
|
def tree
|
1253
1370
|
# Caution: use only for small projects, don't use in root.
|
1254
|
-
$title =
|
1371
|
+
$title = 'Full Tree'
|
1255
1372
|
$files = `zsh -c 'print -rl -- **/*(#{$sorto}#{$hidden}M)'`.split("\n")
|
1256
1373
|
end
|
1374
|
+
|
1257
1375
|
# lists recent files in current dir
|
1258
|
-
#
|
1376
|
+
# In some cases it shows mostly .git files, we need to prune those
|
1259
1377
|
def recent_files
|
1260
1378
|
# print -rl -- **/*(Dom[1,10])
|
1261
|
-
$title =
|
1262
|
-
$files = `zsh -c 'print -rl -- **/*(Dom[1,15])'`.split("\n")
|
1379
|
+
$title = 'Recent files'
|
1380
|
+
$files = `zsh -c 'print -rl -- **/*(Dom[1,15])'`.split("\n").reject {|f| f[0] == '.'}
|
1263
1381
|
end
|
1264
1382
|
|
1265
1383
|
def select_current
|
1266
1384
|
## vp is local there, so i can do $vp[0]
|
1267
|
-
#open_file $view[$sta] if $view[$sta]
|
1385
|
+
# open_file $view[$sta] if $view[$sta]
|
1268
1386
|
open_file $view[$cursor] if $view[$cursor]
|
1269
1387
|
end
|
1270
1388
|
|
1271
1389
|
## create a list of dirs in which some action has happened, for saving
|
1272
|
-
def push_used_dirs
|
1390
|
+
def push_used_dirs(d = Dir.pwd)
|
1273
1391
|
$used_dirs.index(d) || $used_dirs.push(d)
|
1274
1392
|
end
|
1275
|
-
|
1393
|
+
|
1394
|
+
def pbold(text)
|
1276
1395
|
puts "#{BOLD}#{text}#{BOLD_OFF}"
|
1277
1396
|
end
|
1278
|
-
|
1397
|
+
|
1398
|
+
def perror(text)
|
1279
1399
|
puts "#{RED}#{text}#{CLEAR}"
|
1280
1400
|
get_char
|
1281
1401
|
end
|
1282
|
-
|
1402
|
+
|
1403
|
+
def pause(text = ' Press a key ...')
|
1283
1404
|
print text
|
1284
1405
|
get_char
|
1285
1406
|
end
|
1407
|
+
|
1286
1408
|
## return shortcut for an index (offset in file array)
|
1287
1409
|
# use 2 more arrays to make this faster
|
1288
1410
|
# if z or Z take another key if there are those many in view
|
1289
1411
|
# Also, display ROWS * COLS so now we are not limited to 60.
|
1290
|
-
def get_shortcut
|
1291
|
-
return
|
1412
|
+
def get_shortcut(ix)
|
1413
|
+
return '<' if ix < $stact
|
1414
|
+
|
1292
1415
|
ix -= $stact
|
1293
1416
|
i = $IDX[ix]
|
1294
1417
|
return i if i
|
1295
|
-
|
1418
|
+
|
1419
|
+
'->'
|
1296
1420
|
end
|
1421
|
+
|
1297
1422
|
## returns the integer offset in view (file array based on a-y za-zz and Za - Zz
|
1298
1423
|
# Called when user types a key
|
1299
1424
|
# should we even ask for a second key if there are not enough rows
|
1300
1425
|
# What if we want to also trap z with numbers for other purposes
|
1301
|
-
def get_index
|
1426
|
+
def get_index(key, vsz = 999)
|
1302
1427
|
i = $IDX.index(key)
|
1303
|
-
return i
|
1304
|
-
|
1428
|
+
return i + $stact if i
|
1429
|
+
|
1430
|
+
# sz = $IDX.size
|
1305
1431
|
zch = nil
|
1306
1432
|
if vsz > 25
|
1307
|
-
if key ==
|
1433
|
+
if key == 'z' || key == 'Z'
|
1308
1434
|
print key
|
1309
1435
|
zch = get_char
|
1310
1436
|
print zch
|
1311
1437
|
i = $IDX.index("#{key}#{zch}")
|
1312
|
-
return i
|
1438
|
+
return i + $stact if i
|
1313
1439
|
end
|
1314
1440
|
end
|
1315
|
-
|
1441
|
+
nil
|
1316
1442
|
end
|
1317
1443
|
|
1318
1444
|
def delete_file
|
@@ -1323,21 +1449,22 @@ end
|
|
1323
1449
|
# prompt is the user friendly text of command such as list for ls, or extract for dtrx, page for less
|
1324
1450
|
# pauseyn is whether to pause after command as in file or ls
|
1325
1451
|
#
|
1326
|
-
def command_file
|
1452
|
+
def command_file(prompt, *command)
|
1327
1453
|
pauseyn = command.shift
|
1328
|
-
command = command.join
|
1329
|
-
|
1330
|
-
|
1331
|
-
#print "#{prompt} :: Enter file shortcut: "
|
1332
|
-
#file = ask_hint
|
1333
|
-
perror
|
1454
|
+
command = command.join ' '
|
1455
|
+
print "[#{prompt}] Choose a file [#{$view[$cursor]}]: "
|
1456
|
+
file = ask_hint $view[$cursor]
|
1457
|
+
# print "#{prompt} :: Enter file shortcut: "
|
1458
|
+
# file = ask_hint
|
1459
|
+
perror 'Command Cancelled' unless file
|
1334
1460
|
return unless file
|
1461
|
+
|
1335
1462
|
file = File.expand_path(file)
|
1336
|
-
if File.
|
1463
|
+
if File.exist? file
|
1337
1464
|
file = Shellwords.escape(file)
|
1338
1465
|
pbold "#{command} #{file} (#{pauseyn})"
|
1339
1466
|
system "#{command} #{file}"
|
1340
|
-
pause if pauseyn ==
|
1467
|
+
pause if pauseyn == 'y'
|
1341
1468
|
refresh
|
1342
1469
|
else
|
1343
1470
|
perror "File #{file} not found"
|
@@ -1346,31 +1473,30 @@ end
|
|
1346
1473
|
|
1347
1474
|
## prompt user for file shortcut and return file or nil
|
1348
1475
|
#
|
1349
|
-
def ask_hint
|
1476
|
+
def ask_hint(deflt = nil)
|
1350
1477
|
f = nil
|
1351
1478
|
ch = get_char
|
1352
|
-
if ch ==
|
1353
|
-
|
1354
|
-
end
|
1479
|
+
return deflt if ch == 'ENTER'
|
1480
|
+
|
1355
1481
|
ix = get_index(ch, $viewport.size)
|
1356
1482
|
f = $viewport[ix] if ix
|
1357
|
-
|
1483
|
+
f
|
1358
1484
|
end
|
1359
1485
|
|
1360
1486
|
## check screen size and accordingly adjust some variables
|
1361
1487
|
#
|
1362
1488
|
def screen_settings
|
1363
|
-
$glines =
|
1364
|
-
$gcols =
|
1489
|
+
$glines = `tput lines`.to_i
|
1490
|
+
$gcols = `tput cols`.to_i
|
1365
1491
|
$grows = $glines - 3
|
1366
1492
|
$pagesize = 60
|
1367
|
-
|
1493
|
+
# $gviscols = 3
|
1368
1494
|
$pagesize = $grows * $gviscols
|
1369
1495
|
end
|
1370
1496
|
|
1371
1497
|
## moves column offset so we can reach unindexed columns or entries
|
1372
1498
|
# 0 forward and any other back/prev
|
1373
|
-
def column_next
|
1499
|
+
def column_next(dir = 0)
|
1374
1500
|
if dir == 0
|
1375
1501
|
$stact += $grows
|
1376
1502
|
$stact = 0 if $stact >= $viewport.size
|
@@ -1382,12 +1508,14 @@ end
|
|
1382
1508
|
|
1383
1509
|
# currently i am only passing the action in from the list there as a key
|
1384
1510
|
# I should be able to pass in new actions that are external commands
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1511
|
+
# 2019-03-08 - TODO when a file name changes or moves it must be removed
|
1512
|
+
# from selection
|
1513
|
+
def file_actions(action = nil)
|
1514
|
+
h = { d: :delete, m: :move, r: :rename, v: ENV['EDITOR'] || :vim,
|
1515
|
+
c: :copy, C: :chdir, W: :remspace,
|
1516
|
+
l: :less, s: :most, f: :file, o: :open, x: :dtrx, z: :zip }
|
1517
|
+
# acttext = h[action.to_sym] || action
|
1518
|
+
acttext = action || ''
|
1391
1519
|
file = nil
|
1392
1520
|
|
1393
1521
|
sct = $selected_files.size
|
@@ -1395,11 +1523,20 @@ def file_actions(action=nil)
|
|
1395
1523
|
text = "#{sct} files"
|
1396
1524
|
file = $selected_files
|
1397
1525
|
else
|
1398
|
-
|
1399
|
-
file
|
1526
|
+
# 2019-03-07 - trying out direct deletes
|
1527
|
+
# why were we aksing to select a file when user is on a file
|
1528
|
+
# print "[#{acttext}] Choose a file [#{$view[$cursor]}]: "
|
1529
|
+
# file = ask_hint $view[$cursor]
|
1530
|
+
file = $view[$cursor]
|
1531
|
+
unless file
|
1532
|
+
file = ask_hint $view[$cursor]
|
1533
|
+
end
|
1400
1534
|
return unless file
|
1535
|
+
|
1401
1536
|
text = file
|
1402
1537
|
end
|
1538
|
+
# 2019-03-07 - NOTE at this point file can be one or more files.
|
1539
|
+
# 2019-03-07 - text can be a file or count of files, so unreliable !!! FIXME
|
1403
1540
|
|
1404
1541
|
case file
|
1405
1542
|
when Array
|
@@ -1409,67 +1546,138 @@ def file_actions(action=nil)
|
|
1409
1546
|
files = Shellwords.escape(file)
|
1410
1547
|
end
|
1411
1548
|
|
1412
|
-
|
1413
1549
|
ch = nil
|
1414
1550
|
if action
|
1415
|
-
|
1551
|
+
menu_text = action
|
1416
1552
|
else
|
1417
1553
|
ch, menu_text = menu "File Menu for #{text}", h
|
1418
1554
|
menu_text = :quit if ch == 'q'
|
1419
1555
|
end
|
1556
|
+
return unless menu_text # pressed some wrong key
|
1557
|
+
|
1420
1558
|
case menu_text.to_sym
|
1559
|
+
|
1421
1560
|
when :quit
|
1561
|
+
|
1422
1562
|
when :delete
|
1423
|
-
|
1563
|
+
delcommand = 'rmtrash'
|
1564
|
+
print "#{delcommand} #{files} ?[yn]: "
|
1424
1565
|
ch = get_char
|
1425
|
-
return if ch !=
|
1426
|
-
|
1566
|
+
return if ch != 'y'
|
1567
|
+
|
1568
|
+
system "#{delcommand} #{files}"
|
1427
1569
|
refresh
|
1570
|
+
|
1428
1571
|
when :move
|
1572
|
+
# 2019-03-07 - NOTE this will only work with single file selection
|
1429
1573
|
print "move #{text} to : "
|
1430
|
-
#target = gets().chomp
|
1431
|
-
target = Readline
|
1432
|
-
|
1433
|
-
return
|
1574
|
+
# target = gets().chomp
|
1575
|
+
# target = Readline.readline('>', true)
|
1576
|
+
target = readline
|
1577
|
+
return unless target
|
1578
|
+
|
1579
|
+
target = '.' if target == ''
|
1580
|
+
# 2019-03-07 - NOTE cannot use text if multiple files
|
1581
|
+
# text = File.expand_path(text)
|
1582
|
+
target = File.expand_path(target)
|
1583
|
+
return if target == ''
|
1584
|
+
|
1434
1585
|
if File.directory? target
|
1435
|
-
|
1586
|
+
begin
|
1587
|
+
FileUtils.mv file, target
|
1588
|
+
rescue StandardError => exc
|
1589
|
+
perror exc.to_s
|
1590
|
+
end
|
1591
|
+
# 2019-03-08 - TODO if success remove from selection
|
1436
1592
|
refresh
|
1437
1593
|
else
|
1438
|
-
perror
|
1594
|
+
perror 'Target not a dir'
|
1439
1595
|
end
|
1596
|
+
|
1440
1597
|
when :copy
|
1598
|
+
# Target must be directory
|
1441
1599
|
print "copy #{text} to : "
|
1442
|
-
target =
|
1443
|
-
return
|
1444
|
-
|
1445
|
-
target =
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1600
|
+
target = readline
|
1601
|
+
return unless target # C-c
|
1602
|
+
|
1603
|
+
target = '.' if target == ''
|
1604
|
+
target = File.expand_path(target)
|
1605
|
+
return if target == ''
|
1606
|
+
|
1607
|
+
if File.directory? target
|
1608
|
+
begin
|
1609
|
+
FileUtils.cp file, target
|
1610
|
+
rescue StandardError => exc
|
1611
|
+
perror exc.to_s
|
1612
|
+
end
|
1450
1613
|
refresh
|
1614
|
+
else
|
1615
|
+
perror 'Copy target must be a dir'
|
1451
1616
|
end
|
1617
|
+
|
1452
1618
|
when :chdir
|
1453
1619
|
change_dir File.dirname(text)
|
1620
|
+
|
1454
1621
|
when :zip
|
1455
|
-
print
|
1456
|
-
#target = gets().chomp
|
1457
|
-
target = Readline
|
1458
|
-
return if target ==
|
1622
|
+
print 'Archive name: '
|
1623
|
+
# target = gets().chomp
|
1624
|
+
target = Readline.readline('>', true)
|
1625
|
+
return if target == ''
|
1626
|
+
|
1459
1627
|
# don't want a blank space or something screwing up
|
1460
1628
|
if target && target.size > 3
|
1461
|
-
if File.
|
1629
|
+
if File.exist? target
|
1462
1630
|
perror "Target (#{target}) exists"
|
1463
1631
|
else
|
1464
1632
|
system "tar zcvf #{target} #{files}"
|
1465
1633
|
refresh
|
1466
1634
|
end
|
1467
1635
|
end
|
1636
|
+
|
1468
1637
|
when :rename
|
1638
|
+
# 2019-03-07 NOTE works for single file FIXME
|
1639
|
+
# 2019-03-07 - TODO for n files replace pattern with string
|
1640
|
+
print "rename #{text} to : "
|
1641
|
+
target = Readline.readline('>', true)
|
1642
|
+
return if target == ''
|
1643
|
+
|
1644
|
+
text = File.expand_path(text)
|
1645
|
+
target = File.basename(text) if target == '.'
|
1646
|
+
if File.exist? target
|
1647
|
+
perror "Target (#{target}) exists"
|
1648
|
+
else
|
1649
|
+
FileUtils.mv text, target
|
1650
|
+
refresh
|
1651
|
+
end
|
1469
1652
|
when :most, :less, :vim
|
1470
1653
|
system "#{menu_text} #{files}"
|
1654
|
+
# should we remove from selection ?
|
1655
|
+
|
1656
|
+
when :remspace
|
1657
|
+
# 2019-03-08 - 00:07 added replace space with underscore in filename
|
1658
|
+
print "Remove spaces from #{file}"
|
1659
|
+
pause
|
1660
|
+
farray = nil
|
1661
|
+
|
1662
|
+
# stupidly using one variable for scalar and array DUH !
|
1663
|
+
case file
|
1664
|
+
when String
|
1665
|
+
farray = [file]
|
1666
|
+
when Array
|
1667
|
+
farray = file
|
1668
|
+
end
|
1669
|
+
|
1670
|
+
farray.each do |f|
|
1671
|
+
if f.index ' '
|
1672
|
+
nname = f.tr(' ', '_')
|
1673
|
+
FileUtils.mv f, nname unless File.exist? nname
|
1674
|
+
# if success then remove from selection
|
1675
|
+
end
|
1676
|
+
end
|
1677
|
+
refresh
|
1471
1678
|
else
|
1472
1679
|
return unless menu_text
|
1680
|
+
|
1473
1681
|
print "#{menu_text} #{files}"
|
1474
1682
|
pause
|
1475
1683
|
print
|
@@ -1477,13 +1685,16 @@ def file_actions(action=nil)
|
|
1477
1685
|
refresh
|
1478
1686
|
pause
|
1479
1687
|
end
|
1480
|
-
|
1688
|
+
|
1689
|
+
# remove non-existent files from select list due to move or delete
|
1690
|
+
# or rename or whatever
|
1481
1691
|
if sct > 0
|
1482
|
-
$selected_files.
|
1692
|
+
$selected_files.select! { |x| x = File.expand_path(x); File.exist?(x) }
|
1483
1693
|
end
|
1484
1694
|
end
|
1485
1695
|
|
1486
|
-
|
1696
|
+
# increase or decrease column
|
1697
|
+
def columns_incdec(howmany)
|
1487
1698
|
$gviscols += howmany.to_i
|
1488
1699
|
$gviscols = 1 if $gviscols < 1
|
1489
1700
|
$gviscols = 6 if $gviscols > 6
|
@@ -1493,59 +1704,65 @@ end
|
|
1493
1704
|
# bind a key to an external command wich can be then be used for files
|
1494
1705
|
def bindkey_ext_command
|
1495
1706
|
print
|
1496
|
-
pbold
|
1497
|
-
print
|
1707
|
+
pbold 'Bind a capital letter to an external command'
|
1708
|
+
print 'Enter a capital letter to bind: '
|
1498
1709
|
ch = get_char
|
1499
|
-
return if ch ==
|
1710
|
+
return if ch == 'Q'
|
1711
|
+
|
1500
1712
|
if ch =~ /^[A-Z]$/
|
1501
1713
|
print "Enter an external command to bind to #{ch}: "
|
1502
|
-
com = gets
|
1503
|
-
if com !=
|
1504
|
-
print
|
1505
|
-
pro = gets
|
1506
|
-
pro = com if pro ==
|
1714
|
+
com = gets.chomp
|
1715
|
+
if com != ''
|
1716
|
+
print 'Enter prompt for command (blank if same as command): '
|
1717
|
+
pro = gets.chomp
|
1718
|
+
pro = com if pro == ''
|
1507
1719
|
end
|
1508
|
-
print
|
1720
|
+
print 'Pause after output [y/n]: '
|
1509
1721
|
yn = get_char
|
1510
1722
|
$bindings[ch] = "command_file #{pro} #{yn} #{com}"
|
1511
1723
|
end
|
1512
1724
|
end
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
pattern = Readline
|
1517
|
-
return if pattern ==
|
1518
|
-
|
1519
|
-
|
1725
|
+
|
1726
|
+
def ag
|
1727
|
+
print 'Enter a pattern to search (ag): '
|
1728
|
+
pattern = Readline.readline('>', true)
|
1729
|
+
return if pattern == ''
|
1730
|
+
|
1731
|
+
$title = "Files found using 'ag' #{pattern}"
|
1732
|
+
system("ag #{pattern}")
|
1520
1733
|
pause
|
1521
|
-
files = `
|
1522
|
-
if files.
|
1523
|
-
perror
|
1734
|
+
files = `ag -l #{pattern}`.split("\n")
|
1735
|
+
if files.empty?
|
1736
|
+
perror 'No files found.'
|
1524
1737
|
else
|
1525
1738
|
$files = files
|
1526
1739
|
end
|
1527
1740
|
end
|
1741
|
+
|
1528
1742
|
def ffind
|
1529
|
-
print
|
1530
|
-
pattern = Readline
|
1531
|
-
return if pattern ==
|
1743
|
+
print 'Enter a file name pattern to find: '
|
1744
|
+
pattern = Readline.readline('>', true)
|
1745
|
+
return if pattern == ''
|
1746
|
+
|
1532
1747
|
$title = "Files found using 'find' #{pattern}"
|
1533
1748
|
files = `find . -name '#{pattern}'`.split("\n")
|
1534
|
-
if files.
|
1535
|
-
perror
|
1749
|
+
if files.empty?
|
1750
|
+
perror 'No files found.'
|
1536
1751
|
else
|
1537
1752
|
$files = files
|
1538
1753
|
end
|
1539
1754
|
end
|
1755
|
+
|
1540
1756
|
def locate
|
1541
|
-
print
|
1542
|
-
pattern = Readline
|
1543
|
-
return if pattern ==
|
1757
|
+
print 'Enter a file name pattern to locate: '
|
1758
|
+
pattern = Readline.readline('>', true)
|
1759
|
+
return if pattern == ''
|
1760
|
+
|
1544
1761
|
$title = "Files found using 'locate' #{pattern}"
|
1545
1762
|
files = `locate #{pattern}`.split("\n")
|
1546
|
-
files.
|
1547
|
-
if files.
|
1548
|
-
perror
|
1763
|
+
files.select! { |x| x = File.expand_path(x); File.exist?(x) }
|
1764
|
+
if files.empty?
|
1765
|
+
perror 'No files found.'
|
1549
1766
|
else
|
1550
1767
|
$files = files
|
1551
1768
|
end
|
@@ -1555,12 +1772,12 @@ end
|
|
1555
1772
|
# then you can modify this accordingly.
|
1556
1773
|
#
|
1557
1774
|
def viminfo
|
1558
|
-
file = File.expand_path(
|
1559
|
-
if File.
|
1560
|
-
$title =
|
1561
|
-
|
1775
|
+
file = File.expand_path('~/.viminfo')
|
1776
|
+
if File.exist? file
|
1777
|
+
$title = 'Files from ~/.viminfo'
|
1778
|
+
# $files = `grep '^>' ~/.viminfo | cut -d ' ' -f 2- | sed "s#~#$HOME#g"`.split("\n")
|
1562
1779
|
$files = `grep '^>' ~/.viminfo | cut -d ' ' -f 2- `.split("\n")
|
1563
|
-
$files.
|
1780
|
+
$files.select! { |x| x = File.expand_path(x); File.exist?(x) }
|
1564
1781
|
end
|
1565
1782
|
end
|
1566
1783
|
|
@@ -1568,43 +1785,49 @@ end
|
|
1568
1785
|
# modify this accordingly
|
1569
1786
|
#
|
1570
1787
|
def z_interface
|
1571
|
-
file = File.expand_path(
|
1572
|
-
if File.
|
1573
|
-
$title =
|
1788
|
+
file = File.expand_path('~/.z')
|
1789
|
+
if File.exist? file
|
1790
|
+
$title = 'Directories from ~/.z'
|
1574
1791
|
$files = `sort -rn -k2 -t '|' ~/.z | cut -f1 -d '|'`.split("\n")
|
1575
1792
|
home = ENV['HOME']
|
1576
1793
|
$files.collect! do |f|
|
1577
|
-
f.sub(/#{home}/,
|
1794
|
+
f.sub(/#{home}/, '~')
|
1578
1795
|
end
|
1579
1796
|
end
|
1580
1797
|
end
|
1581
1798
|
|
1799
|
+
def vidir
|
1800
|
+
system "vidir"
|
1801
|
+
end
|
1582
1802
|
## there is no one consisten way i am getting.
|
1583
1803
|
# i need to do a shell join if I am to pipe ffiles to say: xargs ls -t
|
1584
1804
|
# but if i want to pipe names to grep xxx then i need to join with newlines
|
1585
|
-
def pipe
|
1586
|
-
end
|
1805
|
+
def pipe; end
|
1587
1806
|
|
1588
1807
|
## some cursor movement functions
|
1589
1808
|
##
|
1590
1809
|
#
|
1591
1810
|
def cursor_scroll_dn
|
1592
|
-
moveto(pos
|
1811
|
+
moveto(pos + MSCROLL)
|
1593
1812
|
end
|
1813
|
+
|
1594
1814
|
def cursor_scroll_up
|
1595
|
-
moveto(pos
|
1815
|
+
moveto(pos - MSCROLL)
|
1596
1816
|
end
|
1817
|
+
|
1597
1818
|
def cursor_dn
|
1598
|
-
moveto(pos
|
1819
|
+
moveto(pos + 1)
|
1599
1820
|
end
|
1821
|
+
|
1600
1822
|
def cursor_up
|
1601
|
-
moveto(pos
|
1823
|
+
moveto(pos - 1)
|
1602
1824
|
end
|
1825
|
+
|
1603
1826
|
def pos
|
1604
1827
|
$cursor
|
1605
1828
|
end
|
1606
1829
|
|
1607
|
-
def moveto
|
1830
|
+
def moveto(pos)
|
1608
1831
|
orig = $cursor
|
1609
1832
|
$cursor = pos
|
1610
1833
|
$cursor = [$cursor, $view.size - 1].min
|
@@ -1613,21 +1836,62 @@ def moveto pos
|
|
1613
1836
|
fin = [orig, $cursor].max
|
1614
1837
|
if $visual_mode
|
1615
1838
|
# PWD has to be there in selction
|
1616
|
-
|
1839
|
+
# TODO: add full path TESTME
|
1840
|
+
if selected? current_file
|
1617
1841
|
# this depends on the direction
|
1618
|
-
$selected_files = $selected_files - $view[star..fin]
|
1842
|
+
# $selected_files = $selected_files - $view[star..fin]
|
1843
|
+
remove_from_selection $view[star..fin]
|
1619
1844
|
## current row remains in selection always.
|
1620
|
-
|
1845
|
+
add_to_selection current_file
|
1621
1846
|
else
|
1622
|
-
$selected_files.concat $view[star..fin]
|
1847
|
+
# $selected_files.concat $view[star..fin]
|
1848
|
+
add_to_selection $view[star..fin]
|
1623
1849
|
end
|
1624
1850
|
end
|
1625
1851
|
end
|
1852
|
+
|
1853
|
+
# is given file in selected array
|
1854
|
+
def selected?(file)
|
1855
|
+
$current_dir ||= Dir.pwd
|
1856
|
+
file = File.join($current_dir, file)
|
1857
|
+
return $selected_files.index file
|
1858
|
+
end
|
1859
|
+
|
1860
|
+
# TODO: can be array
|
1861
|
+
def add_to_selection(file)
|
1862
|
+
ff = file
|
1863
|
+
case file
|
1864
|
+
when String
|
1865
|
+
ff = [file]
|
1866
|
+
end
|
1867
|
+
$current_dir ||= Dir.pwd
|
1868
|
+
ff.each do |f|
|
1869
|
+
full = File.join($current_dir, f)
|
1870
|
+
$selected_files.push full
|
1871
|
+
end
|
1872
|
+
end
|
1873
|
+
|
1874
|
+
# TODO: can be array
|
1875
|
+
def remove_from_selection(file)
|
1876
|
+
ff = file
|
1877
|
+
case file
|
1878
|
+
when String
|
1879
|
+
ff = [file]
|
1880
|
+
end
|
1881
|
+
$current_dir ||= Dir.pwd
|
1882
|
+
ff.each do |f|
|
1883
|
+
full = File.join($current_dir, f)
|
1884
|
+
$selected_files.delete full
|
1885
|
+
end
|
1886
|
+
end
|
1887
|
+
|
1626
1888
|
def visual_mode_toggle
|
1627
1889
|
$visual_mode = !$visual_mode
|
1628
1890
|
if $visual_mode
|
1629
1891
|
$visual_block_start = $cursor
|
1630
|
-
|
1892
|
+
# TODO: add full path TESTME
|
1893
|
+
# $selected_files.push $view[$cursor]
|
1894
|
+
add_to_selection current_file
|
1631
1895
|
end
|
1632
1896
|
end
|
1633
1897
|
|
@@ -1635,69 +1899,77 @@ def visual_block_clear
|
|
1635
1899
|
if $visual_block_start
|
1636
1900
|
star = [$visual_block_start, $cursor].min
|
1637
1901
|
fin = [$visual_block_start, $cursor].max
|
1638
|
-
|
1902
|
+
# TODO: add full path TESTME
|
1903
|
+
# $selected_files = $selected_files - $view[star..fin]
|
1904
|
+
remove_from_selection $view[star..fin]
|
1639
1905
|
end
|
1640
1906
|
$visual_block_start = nil
|
1641
1907
|
$visual_mode = nil
|
1642
1908
|
end
|
1643
1909
|
|
1644
|
-
def file_starting_with
|
1645
|
-
ix = return_next_match(method(:file_matching?), "^#{
|
1646
|
-
if ix
|
1647
|
-
goto_line ix
|
1648
|
-
end
|
1910
|
+
def file_starting_with(first_char)
|
1911
|
+
ix = return_next_match(method(:file_matching?), "^#{first_char}")
|
1912
|
+
goto_line ix if ix
|
1649
1913
|
end
|
1650
|
-
|
1914
|
+
|
1915
|
+
def file_matching?(file, patt)
|
1651
1916
|
file =~ /#{patt}/
|
1652
1917
|
end
|
1653
1918
|
|
1654
1919
|
## generic method to take cursor to next position for a given condition
|
1655
|
-
def return_next_match
|
1920
|
+
def return_next_match(binding, *args)
|
1656
1921
|
first = nil
|
1657
1922
|
ix = 0
|
1658
|
-
$view.each_with_index do |elem,ii|
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1923
|
+
$view.each_with_index do |elem, ii|
|
1924
|
+
next unless binding.call(elem, *args)
|
1925
|
+
|
1926
|
+
first ||= ii
|
1927
|
+
if ii > $cursor
|
1928
|
+
ix = ii
|
1929
|
+
break
|
1665
1930
|
end
|
1666
1931
|
end
|
1667
1932
|
return first if ix == 0
|
1668
|
-
|
1933
|
+
|
1934
|
+
ix
|
1669
1935
|
end
|
1936
|
+
|
1670
1937
|
##
|
1671
1938
|
# position cursor on a specific line which could be on a nother page
|
1672
1939
|
# therefore calculate the correct start offset of the display also.
|
1673
|
-
def goto_line
|
1674
|
-
pages = ((pos * 1.00)
|
1940
|
+
def goto_line(pos)
|
1941
|
+
pages = ((pos * 1.00) / $pagesize).ceil
|
1675
1942
|
pages -= 1
|
1676
1943
|
$sta = pages * $pagesize + 1
|
1677
1944
|
$cursor = pos
|
1678
1945
|
end
|
1679
|
-
|
1946
|
+
|
1947
|
+
def filetype(f)
|
1680
1948
|
return nil unless f
|
1949
|
+
|
1681
1950
|
f = Shellwords.escape(f)
|
1682
1951
|
s = `file #{f}`
|
1683
|
-
if s.index
|
1952
|
+
if s.index 'text'
|
1684
1953
|
return :text
|
1685
1954
|
elsif s.index(/[Zz]ip/)
|
1686
1955
|
return :zip
|
1687
|
-
elsif s.index(
|
1956
|
+
elsif s.index('archive')
|
1688
1957
|
return :zip
|
1689
|
-
elsif s.index
|
1958
|
+
elsif s.index 'image'
|
1690
1959
|
return :image
|
1691
|
-
elsif s.index
|
1960
|
+
elsif s.index 'data'
|
1692
1961
|
return :text
|
1693
1962
|
end
|
1963
|
+
|
1694
1964
|
nil
|
1695
1965
|
end
|
1696
1966
|
|
1697
1967
|
def save_dir_pos
|
1698
1968
|
return if $sta == 0 && $cursor == 0
|
1969
|
+
|
1699
1970
|
$dir_position[Dir.pwd] = [$sta, $cursor]
|
1700
1971
|
end
|
1972
|
+
|
1701
1973
|
def revert_dir_pos
|
1702
1974
|
$sta = 0
|
1703
1975
|
$cursor = 0
|
@@ -1706,50 +1978,108 @@ def revert_dir_pos
|
|
1706
1978
|
$sta = a.first
|
1707
1979
|
$cursor = a[1]
|
1708
1980
|
raise "sta is nil for #{Dir.pwd} : #{$dir_position[Dir.pwd]}" unless $sta
|
1709
|
-
raise
|
1981
|
+
raise 'cursor is nil' unless $cursor
|
1710
1982
|
end
|
1711
1983
|
end
|
1984
|
+
|
1712
1985
|
def newdir
|
1713
1986
|
print
|
1714
|
-
print
|
1715
|
-
str = Readline
|
1716
|
-
return if str ==
|
1717
|
-
|
1987
|
+
print 'Enter directory name: '
|
1988
|
+
str = Readline.readline('>', true)
|
1989
|
+
return if str == ''
|
1990
|
+
|
1991
|
+
if File.exist? str
|
1718
1992
|
perror "#{str} exists."
|
1719
1993
|
return
|
1720
1994
|
end
|
1721
1995
|
begin
|
1722
1996
|
FileUtils.mkdir str
|
1723
|
-
$used_dirs.insert(0, str) if File.
|
1997
|
+
$used_dirs.insert(0, str) if File.exist?(str)
|
1724
1998
|
refresh
|
1725
1999
|
rescue Exception => ex
|
1726
2000
|
perror "Error in newdir: #{ex}"
|
1727
2001
|
end
|
1728
2002
|
end
|
2003
|
+
|
1729
2004
|
def newfile
|
1730
2005
|
print
|
1731
|
-
print
|
1732
|
-
str = Readline
|
1733
|
-
return if str ==
|
1734
|
-
|
1735
|
-
|
2006
|
+
print 'Enter file name: '
|
2007
|
+
str = Readline.readline('>', true)
|
2008
|
+
return if str == ''
|
2009
|
+
|
2010
|
+
# FIXME a file with space will not create single file
|
2011
|
+
# 2019-03-10 - maybe touch a file
|
2012
|
+
|
2013
|
+
system %($EDITOR "#{str}")
|
2014
|
+
$visited_files.insert(0, str) if File.exist?(str)
|
1736
2015
|
refresh
|
1737
2016
|
end
|
1738
2017
|
|
2018
|
+
|
2019
|
+
|
2020
|
+
def current_file
|
2021
|
+
$view[$cursor]
|
2022
|
+
end
|
2023
|
+
|
2024
|
+
def current_or_selected_files
|
2025
|
+
return $selected_files if $selected_files.size > 0
|
2026
|
+
|
2027
|
+
return [current_file]
|
2028
|
+
end
|
2029
|
+
|
2030
|
+
# ------------------- scripts ------------------ #
|
2031
|
+
# prompt for scripts to execute, giving selected file names
|
2032
|
+
def scripts
|
2033
|
+
title = 'Select a script'
|
2034
|
+
script_path = '~/.config/cetus/scripts'
|
2035
|
+
binding = `find #{script_path} -type f | fzf --prompt="#{title.to_s} :"`
|
2036
|
+
return unless binding
|
2037
|
+
|
2038
|
+
binding = binding.chomp if binding
|
2039
|
+
# TODO: check if binding is a file and executable
|
2040
|
+
# xargs only seems to take the first file
|
2041
|
+
# cf = current_or_selected_files.join('\0')
|
2042
|
+
# cf = Shellwords.join(current_or_selected_files)
|
2043
|
+
current_or_selected_files.each do |file|
|
2044
|
+
system %( #{binding} "#{file}" )
|
2045
|
+
end
|
2046
|
+
# system %(echo "#{cf}" | xargs #{binding})
|
2047
|
+
pause
|
2048
|
+
end
|
2049
|
+
# ------------- end of scripts --------------------------------#
|
2050
|
+
|
2051
|
+
# ------------------- page_selection ------------------ #
|
2052
|
+
def page_selection
|
2053
|
+
require 'tempfile'
|
2054
|
+
file = Tempfile.new('selected_files')
|
2055
|
+
begin
|
2056
|
+
$selected_files.each { |row| file.puts row }
|
2057
|
+
file.flush
|
2058
|
+
system "$PAGER #{file.path}"
|
2059
|
+
rescue
|
2060
|
+
file.close
|
2061
|
+
file.unlink
|
2062
|
+
end
|
2063
|
+
end
|
2064
|
+
# ------------- end of page_selection --------------------------------#
|
1739
2065
|
##
|
1740
2066
|
# Editing of the User Dir List.
|
1741
2067
|
# remove current entry from used dirs list, since we may not want some entries being there
|
1742
2068
|
#
|
1743
2069
|
def remove_from_list
|
1744
|
-
|
2070
|
+
unless $selected_files.empty?
|
1745
2071
|
sz = $selected_files.size
|
1746
2072
|
print "Remove #{sz} files from used list (y)?: "
|
1747
2073
|
ch = get_char
|
1748
|
-
return if ch !=
|
1749
|
-
|
1750
|
-
|
2074
|
+
return if ch != 'y'
|
2075
|
+
|
2076
|
+
arr = $selected_files.map { |path| File.expand_path(path) }
|
2077
|
+
|
2078
|
+
$used_dirs = $used_dirs - arr
|
2079
|
+
$visited_files = $visited_files - arr
|
1751
2080
|
unselect_all
|
1752
2081
|
$modified = true
|
2082
|
+
refresh
|
1753
2083
|
return
|
1754
2084
|
end
|
1755
2085
|
print
|
@@ -1757,7 +2087,8 @@ def remove_from_list
|
|
1757
2087
|
file = $view[$cursor]
|
1758
2088
|
print "Remove #{file} from used list (y)?: "
|
1759
2089
|
ch = get_char
|
1760
|
-
return if ch !=
|
2090
|
+
return if ch != 'y'
|
2091
|
+
|
1761
2092
|
file = File.expand_path(file)
|
1762
2093
|
if File.directory? file
|
1763
2094
|
$used_dirs.delete(file)
|
@@ -1767,6 +2098,7 @@ def remove_from_list
|
|
1767
2098
|
refresh
|
1768
2099
|
$modified = true
|
1769
2100
|
end
|
2101
|
+
|
1770
2102
|
#
|
1771
2103
|
# If there's a short file list, take recently mod and accessed folders and put latest
|
1772
2104
|
# files from there and insert it here. I take both since recent mod can be binaries / object
|
@@ -1775,15 +2107,16 @@ end
|
|
1775
2107
|
# include files.
|
1776
2108
|
def enhance_file_list
|
1777
2109
|
return unless $enhanced_mode
|
2110
|
+
|
1778
2111
|
# if only one entry and its a dir
|
1779
2112
|
# get its children and maybe the recent mod files a few
|
1780
2113
|
|
1781
2114
|
if $files.size == 1
|
1782
2115
|
# its a dir, let give the next level at least
|
1783
|
-
if $files.first[-1] ==
|
2116
|
+
if $files.first[-1] == '/'
|
1784
2117
|
d = $files.first
|
1785
2118
|
f = `zsh -c 'print -rl -- #{d}*(omM)'`.split("\n")
|
1786
|
-
if f && f.
|
2119
|
+
if f && !f.empty?
|
1787
2120
|
$files.concat f
|
1788
2121
|
$files.concat get_important_files(d)
|
1789
2122
|
return
|
@@ -1797,28 +2130,28 @@ def enhance_file_list
|
|
1797
2130
|
# check if a ruby project dir, although it could be a backup file too,
|
1798
2131
|
# if so , expand lib and maby bin, put a couple recent files
|
1799
2132
|
#
|
1800
|
-
if $files.index(
|
2133
|
+
if $files.index('Gemfile') || !$files.grep(/\.gemspec/).empty?
|
1801
2134
|
# usually the lib dir has only one file and one dir
|
1802
2135
|
flg = false
|
1803
2136
|
$files.concat get_important_files(Dir.pwd)
|
1804
|
-
if $files.index(
|
2137
|
+
if $files.index('lib/')
|
1805
2138
|
f = `zsh -c 'print -rl -- lib/*(om[1,5]M)'`.split("\n")
|
1806
|
-
if f && f.
|
1807
|
-
insert_into_list(
|
2139
|
+
if f && !f.empty?
|
2140
|
+
insert_into_list('lib/', f)
|
1808
2141
|
flg = true
|
1809
2142
|
end
|
1810
2143
|
dd = File.basename(Dir.pwd)
|
1811
2144
|
if f.index("lib/#{dd}/")
|
1812
2145
|
f = `zsh -c 'print -rl -- lib/#{dd}/*(om[1,5]M)'`.split("\n")
|
1813
|
-
if f && f.
|
2146
|
+
if f && !f.empty?
|
1814
2147
|
insert_into_list("lib/#{dd}/", f)
|
1815
2148
|
flg = true
|
1816
2149
|
end
|
1817
2150
|
end
|
1818
2151
|
end
|
1819
|
-
if $files.index(
|
2152
|
+
if $files.index('bin/')
|
1820
2153
|
f = `zsh -c 'print -rl -- bin/*(om[1,5]M)'`.split("\n")
|
1821
|
-
insert_into_list(
|
2154
|
+
insert_into_list('bin/', f) if f && !f.empty?
|
1822
2155
|
flg = true
|
1823
2156
|
end
|
1824
2157
|
return if flg
|
@@ -1830,15 +2163,11 @@ def enhance_file_list
|
|
1830
2163
|
|
1831
2164
|
## first check accessed else modified will change accessed
|
1832
2165
|
moda = `zsh -c 'print -rn -- *(/oa[1]M)'`
|
1833
|
-
if moda && moda !=
|
2166
|
+
if moda && moda != ''
|
1834
2167
|
modf = `zsh -c 'print -rn -- #{moda}*(oa[1]M)'`
|
1835
|
-
if modf && modf !=
|
1836
|
-
insert_into_list moda, modf
|
1837
|
-
end
|
2168
|
+
insert_into_list moda, modf if modf && modf != ''
|
1838
2169
|
modm = `zsh -c 'print -rn -- #{moda}*(om[1]M)'`
|
1839
|
-
if modm && modm !=
|
1840
|
-
insert_into_list moda, modm
|
1841
|
-
end
|
2170
|
+
insert_into_list moda, modm if modm && modm != '' && modm != modf
|
1842
2171
|
end
|
1843
2172
|
## get last modified dir
|
1844
2173
|
modm = `zsh -c 'print -rn -- *(/om[1]M)'`
|
@@ -1853,38 +2182,38 @@ def enhance_file_list
|
|
1853
2182
|
# are the same dir, so we need to find the second modified dir
|
1854
2183
|
end
|
1855
2184
|
end
|
1856
|
-
|
1857
|
-
|
1858
|
-
#
|
1859
|
-
|
2185
|
+
|
2186
|
+
def insert_into_list(_dir, file)
|
2187
|
+
# ix = $files.index(dir)
|
2188
|
+
# raise "something wrong can find #{dir}." unless ix
|
2189
|
+
# $files.insert ix, *file
|
1860
2190
|
# 2013-03-19 - 19:42 adding at end to avoid confusion
|
1861
|
-
|
2191
|
+
# $files.concat file
|
1862
2192
|
$files.push *file
|
1863
2193
|
end
|
1864
|
-
|
2194
|
+
|
2195
|
+
def get_important_files(dir)
|
1865
2196
|
# checks various lists like visited_files and bookmarks
|
1866
2197
|
# to see if files from this dir or below are in it.
|
1867
2198
|
# More to be used in a dir with few files.
|
1868
2199
|
list = []
|
1869
2200
|
l = dir.size + 1
|
1870
2201
|
$visited_files.each do |e|
|
1871
|
-
if e.index(dir) == 0
|
1872
|
-
list << e[l..-1]
|
1873
|
-
end
|
2202
|
+
list << e[l..-1] if e.index(dir) == 0
|
1874
2203
|
end
|
1875
2204
|
# bookmarks have : which needs to be removed
|
1876
|
-
#list1 = $bookmarks.values.select do |e|
|
1877
|
-
|
1878
|
-
#end
|
1879
|
-
#list.concat list1
|
1880
|
-
|
2205
|
+
# list1 = $bookmarks.values.select do |e|
|
2206
|
+
# e.index(dir) == 0
|
2207
|
+
# end
|
2208
|
+
# list.concat list1
|
2209
|
+
list
|
1881
2210
|
end
|
1882
2211
|
|
1883
|
-
Signal.trap('EXIT')
|
2212
|
+
Signal.trap('EXIT') do
|
1884
2213
|
reset_terminal
|
1885
2214
|
# system 'tput rmcup'
|
1886
2215
|
exit
|
1887
|
-
|
2216
|
+
end
|
1888
2217
|
run
|
1889
2218
|
# 2019-02-20 - added so alt-screen is used
|
1890
2219
|
system 'tput rmcup'
|