diru 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52998510ee6ded3ea6fa81a826e82e648cbffb1abf1174a985ee71627bfc2d75
4
- data.tar.gz: ee3d26f1d9d6668e67e9eabe0b34402a5b5c7e477d20a6cb58f1d51da4449ab3
3
+ metadata.gz: bff41ddbd0a089a76fbac53809a65e8c63c6fd3b8e41840d7fe2319e3452ad8c
4
+ data.tar.gz: b0ab6420120c5bf94cfa55bf62f7de4433b99997c5e68e7a12391c7154aa9321
5
5
  SHA512:
6
- metadata.gz: f4dbaef3dc53c31010493374b2feefd8c15f01a2e1cbfac777ccee14e7488208b3f27c195abd2ce4d51d5ebfe34493bba734551d4ef6ff9b2cbe4bae8ac6a9ff
7
- data.tar.gz: bb18dc7513830cfbbf4b2b33ef07aa084ccb2b44c4f01ba3b722b81c4d4c60f29b4f82a82d181302acd0847401738542436f08f6eebd62da8e9da87dc49bd3b1
6
+ metadata.gz: 5748973d952b6bc716ec76f5caa4d9fd6073947f35f65206e037b98b04fcdc7c2125ab4e4fb94ddc9b410fc15dfb0587bd1a7e2535f32203ff32036dc78284ab
7
+ data.tar.gz: 16ba39420fee22cd668235edfeba88e7629659a30e1510af1f975fc7eea11a847f7c826a5313d98c7d0fdd1c646f01fa3466c0725004557b6c5a58837465b1fb
@@ -1,5 +1,8 @@
1
1
  = Version history
2
2
 
3
+ [0.1.2] Key/value lookup feature.
4
+ Updates to documentation.
5
+
3
6
  [0.1.1] Prefering string keys for config.
4
7
  Prefer json over yaml for options.
5
8
  Deprecated DIRU_OPTS_FORMAT env var.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017 tero.isannainen@gmail.com
1
+ Copyright (c) 2017, 2019 tero.isannainen@gmail.com
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,6 +1,7 @@
1
1
  = Diru
2
2
 
3
3
  * Introduction
4
+ * Quick start guide
4
5
  * Getting started
5
6
  * Client commands
6
7
  * Configuration
@@ -10,7 +11,7 @@
10
11
 
11
12
  Diru is a Change Directory (cd) utility for augmenting Unix Shell
12
13
  functionality. Diru makes it easy and efficient to jump around in
13
- Project's directories. Diru uses server/client architecture, which
14
+ Project's directories. Diru uses client/server architecture, which
14
15
  enables sharing of directory info and state between terminal sessions.
15
16
 
16
17
  Each Server serves one Project. Project is a tree of related
@@ -19,29 +20,94 @@ root. There can be multiple Servers, if user needs to access multiple
19
20
  Projects concurrently.
20
21
 
21
22
  Client queries directory info from Server and directory change is
22
- pushed to Shell in order to change the current directory within
23
+ pushed to Shell in order to change the current directory within the
23
24
  Shell. Diru is not able to change the Shell directory by itself. User
24
- must define a Shell function which can actually change the state of
25
+ must define a Shell function which can actually modify the state of
25
26
  the Shell.
26
27
 
28
+
27
29
  Diru features:
28
30
 
29
31
  * Support for multiple concurrent Projects.
32
+
30
33
  * User and Project specific options (configuration).
34
+
31
35
  * Jump to Project root.
36
+
32
37
  * Find and jump to dir under Project root (glob and regex search).
38
+
33
39
  * Find and jump to dir under current dir (glob search).
40
+
34
41
  * Fast directory search since Server maintains a memory image of
35
42
  directories.
36
- * Favorite directories in options (configuration), for permanent
37
- favorites.
43
+
44
+ * Configurable favorite directories, for persistent favorites.
45
+
38
46
  * Bookmark saving and referencing, for current favorites.
47
+
39
48
  * Directory change history and history referencing.
49
+
40
50
  * Scratch Pad (with named regs) for directory copy/paste.
51
+
41
52
  * Peer directory jumping, i.e. peer of current (regexp match).
53
+
54
+ * Key/value store (Lookup) for general purpose information exchange
55
+ between terminals.
56
+
42
57
  * Online help.
43
58
 
44
59
 
60
+
61
+ = Quick start guide
62
+
63
+ This section defines a minimal number of steps for using Diru. The
64
+ description applies to a single server setup.
65
+
66
+ == Step 1
67
+
68
+ Define function (Bourne Shell) for using Diru Client:
69
+
70
+ dr()
71
+ {
72
+ ret=`diru -p 41115 -c $*`
73
+ if test $? -eq 0; then
74
+ cd $ret
75
+ fi
76
+ }
77
+
78
+ == Step 2
79
+
80
+ Setup project configuration:
81
+
82
+ shell> cd my_project
83
+ shell> diru -t > .diru.json
84
+
85
+ == Step 3
86
+
87
+ Start Diru Hub and default Diru Server for "my_project":
88
+
89
+ shell> diru --start
90
+
91
+ == Step 4
92
+
93
+ Use Client to store current directory to Scratch Pad:
94
+
95
+ shell> dr s .
96
+
97
+ Use Client as usual.
98
+
99
+ == Step 5
100
+
101
+ Kill all Servers and the Hub:
102
+
103
+ shell> diru --hkill
104
+
105
+ The Client was ready to use, but ".diru.json" included the default
106
+ template, which should be customized with project related
107
+ values. Modify the configuration before starting Hub and Server again.
108
+
109
+
110
+
45
111
  = Getting started
46
112
 
47
113
  The first thing to do is to start Diru Hub. Hub is a server process
@@ -72,15 +138,15 @@ Hub.
72
138
 
73
139
  When Server starts, it will detect the Project root. It can be a file
74
140
  or defined as environment variable. Environment variable DIRU_ROOT has
75
- higher precedence than the files. If ".diru_root_dir" file or a
76
- ".diru.[json|yml]" file is found from current dir or some dir above,
77
- the dir containing either of the files will become the Project
78
- root. If no files are found and DIRU_ROOT environment variable is not
79
- used, an error is issued.
141
+ higher precedence than a file based root. If ".diru_root_dir" file or
142
+ a ".diru.json" (or ".diru.yml") file is found from current dir or some
143
+ dir above, the dir containing either of the files will become the
144
+ Project root. If no files are found and DIRU_ROOT environment variable
145
+ is not used, an error is issued.
80
146
 
81
147
  Client communicates with the Server in order to get and save directory
82
148
  info. As mentioned above, Diru is more or less useless unless user has
83
- defined a Shell function to realize directory changing.
149
+ defined a Shell function to realize the directory changes.
84
150
 
85
151
  Here is an example of such function for Bourne Shell based shells:
86
152
 
@@ -92,11 +158,11 @@ Here is an example of such function for Bourne Shell based shells:
92
158
  fi
93
159
  }
94
160
 
95
- Diru Client command is called now "dr". We specify with "-p" option,
96
- that port "42324" is used towards the Server and with "-c" that we
97
- want to issue directory "change" commands. In practice only part of
98
- the commands will change directory, since some commands are only for
99
- queries. Directory is (and should be) changed if Diru returns
161
+ Diru Client command is defined as "dr" now. Option "-p" defines that
162
+ port "42324" is used to identify the Server and option "-c" defines
163
+ that we want to issue directory "change" commands. In practice only
164
+ part of the commands will change directory, since some commands are
165
+ only for queries. Directory is (and should be) changed if Diru returns
100
166
  0. Otherwise Diru is performing a non-cd command, and Shell should
101
167
  just ignore the current Diru execution.
102
168
 
@@ -126,7 +192,7 @@ to previous dir, we do:
126
192
 
127
193
  shell> dr h 0
128
194
 
129
- Bookmarks have also the same type of number based referencing.
195
+ Bookmarks have the same type of number based referencing.
130
196
 
131
197
  User can create a command sequence by separating commands with ","
132
198
  character. For example if you want to reference Scratch Pad and then
@@ -142,14 +208,17 @@ info from Server.
142
208
 
143
209
  Search commands:
144
210
 
145
- * "dr r" - change to Project root dir.
146
- * "dr r <dir>" - change to <dir> (somewhere) under Project root dir
147
- (glob).
148
- * "dr t <dir>" - change to <dir> (somewhere) under current dir (glob).
149
- * "dr e <dir>" - change to <dir> (somewhere) under Project root dir
150
- (regexp).
211
+ dr r:: change to Project root dir.
212
+
213
+ dr r <dir>:: change to <dir> (somewhere) under Project root dir
214
+ (glob).
215
+
216
+ dr t <dir>:: change to <dir> (somewhere) under current dir (glob).
151
217
 
152
- Search can match to multiple directories. First match is used and the
218
+ dr e <dir>:: change to <dir> (somewhere) under Project root dir
219
+ (regexp).
220
+
221
+ Search can match multiple directories. First match is used and the
153
222
  rest (Left-overs) are displayed to the user. Left-overs are also
154
223
  stored, and they can be referenced and used in order of appearance
155
224
  with simply issuing "dr" again.
@@ -166,55 +235,68 @@ automatically match to the middle of the string, however regexp does.
166
235
 
167
236
  Bookmark commands:
168
237
 
169
- * "dr b" - display bookmarks.
170
- * "dr b ." - add current dir to bookmarks.
171
- * "dr b !" - reset (clear) bookmarks.
172
- * "dr b s <file>" - store bookmarks to <file>.
173
- * "dr b l <file>" - load bookmarks from <file>.
174
- * "dr b d <num>" - delete bookmark with <num>.
175
- * "dr b <num>" - change dir to bookmark <num>.
238
+ dr b:: display bookmarks.
239
+ dr b .:: add current dir to bookmarks.
240
+ dr b !:: reset (clear) bookmarks.
241
+ dr b s <file>:: store bookmarks to <file>.
242
+ dr b l <file>:: load bookmarks from <file>.
243
+ dr b d <num>:: delete bookmark with <num>.
244
+ dr b <num>:: change dir to bookmark <num>.
245
+
176
246
 
177
247
  History commands:
178
248
 
179
- * "dr h" - display history.
180
- * "dr h ." - add current dir to history.
181
- * "dr h !" - reset (clear) history.
182
- * "dr h 0" - reference latest history item.
183
- * "dr h <num>" - change dir to history <num>.
249
+ dr h:: display history.
250
+ dr h .:: add current dir to history.
251
+ dr h !:: reset (clear) history.
252
+ dr h ,:: reference latest history item.
253
+ dr h <num>:: change dir to history <num>.
254
+
184
255
 
185
256
  Scratch Pad commands:
186
257
 
187
- * "dr s ." - store current dir to Default Scratch Pad.
188
- * "dr s . <reg>" - store current dir to <reg> in Scratch Pad.
189
- * "dr s <dir>" - store <dir> to Default Scratch Pad.
190
- * "dr s <d> <r>" - store <dir> to <reg> in Scratch Pad.
191
- * "dr s" - change dir to Default Scratch Pad.
192
- * "dr s <reg>" - change dir to <reg> from Scratch Pad.
193
- * "dr s =" - display Scratch Pad content.
194
- * "dr s !" - reset (clear) Scratch Pad.
258
+ dr s .:: store current dir to Default Scratch Pad.
259
+ dr s . <reg>:: store current dir to <reg> in Scratch Pad.
260
+ dr s <dir>:: store <dir> to Default Scratch Pad.
261
+ dr s <d> <r>:: store <dir> to <reg> in Scratch Pad.
262
+ dr s:: change dir to Default Scratch Pad.
263
+ dr s <reg>:: change dir to <reg> from Scratch Pad.
264
+ dr s =:: display Scratch Pad content.
265
+ dr s !:: reset (clear) Scratch Pad.
266
+
267
+
268
+ Lookup commands:
269
+
270
+ dr l:: list all lookup <key>/<v> pairs.
271
+ dr !:: remove all keys.
272
+ dr ! <key>:: remove <key>.
273
+ dr l <key>:: lookup value for <key>.
274
+ dr l <key> <v>:: store value <v> for <key>.
275
+
195
276
 
196
277
  Misc commands:
197
278
 
198
- * "dr p" - jump to peer dir, i.e. the peer of current (from options).
199
- * "dr c <cmd>" - issue RPC command to server (reset etc., see below).
200
- * "dr f" - list favorites dirs (from options).
201
- * "dr f <dir>" - change dir to favorite <dir>.
202
- * "dr d m <dir>" - make directory.
203
- * "dr d r <dir>" - remove directory.
204
- * "dr i" - show command info.
205
- * "dr <dir>" - change to given dir (must be under current).
206
- * "dr" - change to next "Left-over" directory.
279
+ dr p:: jump to peer dir, i.e. the peer of current (from options).
280
+ dr c <cmd>:: issue RPC command to server (reset etc., see below).
281
+ dr f:: list favorites dirs (from options).
282
+ dr f <dir>:: change dir to favorite <dir>.
283
+ dr d m <dir>:: make directory.
284
+ dr d r <dir>:: remove directory.
285
+ dr i:: show command info.
286
+ dr <dir>:: change to given dir (must be under current).
287
+ dr:: change to next "Left-over" directory.
288
+
207
289
 
208
290
  RPC (Remote Procedure Call) commands:
209
291
 
210
- * "reset" - Reset Server state, i.e. History, Bookmarks, Left-overs.
211
- * "abook" - Add current dir to Bookmarks.
212
- * "lbook" - List Bookmarks.
213
- * "rbook" - Reset Bookmarks.
214
- * "doc" - Show command documentation.
215
- * "dsync" - Synchronize Project dir content data with Server cache.
216
- * "sync" - Synchronize Options File content to Server.
217
- * "lregs" - List Scratch Pad registers.
292
+ reset:: Reset Server state, i.e. History, Bookmarks, Left-overs.
293
+ abook:: Add current dir to Bookmarks.
294
+ lbook:: List Bookmarks.
295
+ rbook:: Reset Bookmarks.
296
+ doc:: Show command documentation.
297
+ dsync:: Synchronize Project dir content data with Server cache.
298
+ sync:: Synchronize Options File content to Server.
299
+ lregs:: List Scratch Pad registers.
218
300
 
219
301
 
220
302
  = Configuration
@@ -222,12 +304,15 @@ RPC (Remote Procedure Call) commands:
222
304
  Diru uses several environment variables, which are optional, and
223
305
  provides thereby backup values for non-specified command line info.
224
306
 
225
- * DIRU_HUB_PORT - Hub Port, if nothing, 41114 is used.
226
- * DIRU_PORT - Server Port, if nothing, ~/.diru.prt is used
227
- (Port File).
228
- * DIRU_OPTS - Options file, if nothing, ~/.diru.[json|yml] is used.
229
- * DIRU_ROOT - Project root, used if ".diru_root_dir" and
230
- ".diru.[json|yml]" are missing.
307
+ DIRU_HUB_PORT:: Hub Port, or 41114 if not defined.
308
+
309
+ DIRU_PORT:: Server Port, or "~/.diru.prt" (Port File) if not
310
+ defined. See below for details.
311
+
312
+ DIRU_OPTS:: Options file, or "~/.diru.json" if not defined.
313
+
314
+ DIRU_ROOT:: Project root, which is used if ".diru_root_dir" and
315
+ ".diru.json" are missing.
231
316
 
232
317
  If Hub is started without "--hport" option, Diru checks if
233
318
  DIRU_HUB_PORT is defined. If not, port 41114 is used.
@@ -239,14 +324,14 @@ not work if no port info is given.
239
324
  If Server is started in a directory where (or above) a file called
240
325
  ".diru_root_dir" is found, then Project root is the directory
241
326
  containing ".diru_root_dir". If ".diru_root_dir" is not found, but
242
- ".diru.[json|yml]" is found, then Project root is the directory
243
- containing ".diru.[json|yml]", and Options for Project are taken from
327
+ ".diru.json" is found, then Project root is the directory
328
+ containing ".diru.json", and Options for Project are taken from
244
329
  that file. Last resort for defining Project root, is DIRU_ROOT
245
330
  definition.
246
331
 
247
332
  If ".diru_root_dir" or DIRU_ROOT is used to define Project root, then
248
333
  DIRU_OPTS is used to define Options File. However, if not defined,
249
- then "~/.diru.[json|yml]" is used for options.
334
+ then "~/.diru.json" is used for options.
250
335
 
251
336
  The "json" format is searched before "yml" format, and hence "json" is
252
337
  selected if both exist.
@@ -258,20 +343,20 @@ An example Options file can be displayed with:
258
343
 
259
344
  Available options in Options File:
260
345
 
261
- * sync - Options File and Project directory hierarchy refresh period
262
- in seconds (for Server).
346
+ sync:: Options File and Project directory hierarchy refresh period
347
+ in seconds (for Server).
263
348
 
264
- * dsync - Project directory hierarchy refresh period. This overrides
265
- "sync" for Project updates (only). If value is 0, then no
266
- updates are done after initial update when Server
267
- starts. User might want to use 0, if the directory
268
- hierarchy is big and/or does not change (often).
349
+ dsync:: Project directory hierarchy refresh period. This overrides
350
+ "sync" for Project updates (only). If value is 0, then no
351
+ updates are done after initial update when Server starts. User
352
+ might want to use 0, if the directory hierarchy is big and/or
353
+ does not change (often).
269
354
 
270
- * hist - number of entries in history (max).
355
+ hist:: number of entries in history (max).
271
356
 
272
- * favs - tagged favorite dirs.
357
+ favs:: tagged favorite dirs.
273
358
 
274
- * peers - <regexp>,<str> pairs for peer matching (String#sub method).
359
+ peers:: <regexp>,<str> pairs for peer matching (String#sub method).
275
360
 
276
361
 
277
362
  = Practical usage tips
@@ -284,8 +369,9 @@ Project. Depending on the usage pattern, user might as well want to
284
369
  use the Port File.
285
370
 
286
371
  Each Project could benefit from specific Options File, and hence user
287
- can mark the Project Root with ".diru.[json|yml]" and specify the
288
- Project setup there.
372
+ can mark the Project Root with ".diru.json" (or ".diru.yml") and
373
+ specify the Project setup there. Default is to define the Project Root
374
+ with a ".diru.json" file.
289
375
 
290
376
  Server caches all Project directory entries from disk to memory. This
291
377
  means that Client can quickly jump to any directory, even deep in the
@@ -294,7 +380,7 @@ otherwise the search results in too many Left-overs, which is
294
380
  impractical. Server updates the cache either periodically or only at
295
381
  start-up. User might prefer no automatic update, if the hierarchy is
296
382
  very large and extra load on disk is to be avoided. Cache update can
297
- be performed at will with an RPC call, "dsync".
383
+ be performed, anyhow, at will with an RPC call, "dsync".
298
384
 
299
385
  If user is working with a programming project, it is fairly common to
300
386
  have separate sub-directories for source code and build targets. Let's
@@ -316,4 +402,14 @@ Options File can be edited while Server is running. Server reads the
316
402
  Options File every 5 seconds (configurable with "sync") and refreshes
317
403
  its internal state. Server also updates its internal cache of Project
318
404
  directory content at each refresh cycle (by default). If "dsync"
319
- Option is specified, it defines the "dsync" rate.
405
+ Option is specified, it defines the "dsync" rate specifically.
406
+
407
+ The "dr" Shell function is in practice compulsory. In addition to "dr"
408
+ function, it is convenient to have a "dri" function. "dri" is meant
409
+ for interactive queries only, and obviously can have any name the user
410
+ wants.
411
+
412
+ dri() { diru -p 42324 -c $* 2>&1 }
413
+
414
+ This function returns Diru stderr responses as stdout and hence it is
415
+ easy to pipe this to other Shell commands.
data/bin/diru CHANGED
@@ -73,6 +73,7 @@ Spec.command( 'diru', 'Tero Isannainen', '2017',
73
73
  [ :opt_single, 'hport', nil, "H: Hub port (default: DIRU_HUB_PORT or 41114)." ],
74
74
  [ :switch, 'hkill', nil, "H: Kill hub." ],
75
75
  [ :switch, 'nodaemon', nil, "H: No daemon for server." ],
76
+ [ :switch, 'start', nil, "HS: Start hub and default server." ],
76
77
  [ :opt_any, 'server', '-s', "S: Open server for user (default: $USER)." ],
77
78
  [ :opt_single, 'kill', '-k', "S: Close server." ],
78
79
  [ :switch, 'list', '-l', "S: List servers." ],
@@ -103,13 +104,16 @@ module Diru
103
104
  @conf = conf_file.load
104
105
  end
105
106
 
106
-
107
107
  # Error message display.
108
- def Diru.error( msg )
108
+ def Diru.error_msg( msg )
109
109
  STDERR.puts "Diru Error: #{msg}"
110
- exit( false )
111
110
  end
112
111
 
112
+ # Error message display with exit.
113
+ def Diru.error( msg )
114
+ Diru.error_msg( msg )
115
+ exit( false )
116
+ end
113
117
 
114
118
  # Warning message display.
115
119
  def Diru.warn( msg )
@@ -181,15 +185,6 @@ module Diru
181
185
  found
182
186
  end
183
187
 
184
-
185
- def Diru.opts_filename
186
- if ENV['DIRU_OPTS_FORMAT']
187
- ".diru.#{ENV['DIRU_OPTS_FORMAT']}"
188
- else
189
- ".diru.yml"
190
- end
191
- end
192
-
193
188
  end
194
189
 
195
190
 
@@ -281,6 +276,9 @@ class Search
281
276
  # Favorites.
282
277
  @fav = {}
283
278
 
279
+ # Lookup database.
280
+ @lut = {}
281
+
284
282
  # History limit.
285
283
  @histlimit = 20
286
284
 
@@ -488,6 +486,34 @@ class Search
488
486
  end
489
487
 
490
488
 
489
+ # Return LUT, key/value store entries.
490
+ def lut
491
+ @lut
492
+ end
493
+
494
+
495
+ # Reset LUT entry or all entries.
496
+ def rlut( key = nil )
497
+ if key
498
+ @lut.delete key
499
+ else
500
+ @lut = {}
501
+ end
502
+ end
503
+
504
+
505
+ # Get value from LUT.
506
+ def getlut( key )
507
+ @lut[ key ]
508
+ end
509
+
510
+
511
+ # Set value in LUT.
512
+ def setlut( key, value )
513
+ @lut[ key ] = value
514
+ end
515
+
516
+
491
517
  def abs2rel( path )
492
518
  if path == @root
493
519
  ''
@@ -646,6 +672,7 @@ class Search
646
672
  @old = []
647
673
  @book = []
648
674
  @hist = []
675
+ @lut = {}
649
676
  update_data_sync
650
677
  end
651
678
 
@@ -760,11 +787,9 @@ class Hub
760
787
  # Kill hub.
761
788
  def kill
762
789
  @th = Thread.new do
763
- STDERR.puts "Diru Hub: Exiting sooooon..."
764
- sleep 3
790
+ STDERR.puts "Diru Hub: Killing servers ..."
765
791
  kill_servers
766
- sleep 3
767
- STDERR.puts "Diru Hub: Exit done..."
792
+ STDERR.puts "Diru Hub: Exit done ..."
768
793
  @hub.stop_service
769
794
  exit( false )
770
795
  end
@@ -805,7 +830,14 @@ class Hub
805
830
  def kill_server( s_port )
806
831
  s = @@servers[ s_port ]
807
832
  if s
808
- s.kill
833
+ alive = s.alive?
834
+ cnt = 0
835
+ while alive && cnt < 20
836
+ s.kill
837
+ sleep 0.1
838
+ alive = s.alive?
839
+ cnt += 1
840
+ end
809
841
  @@servers.delete( s_port )
810
842
  else
811
843
  nil
@@ -816,9 +848,87 @@ end
816
848
 
817
849
 
818
850
 
819
- # diru client service (server) thread.
851
+ # Diru client service (server) thread.
820
852
  class Service
821
853
 
854
+ def Service.start( hport, user, try_cnt = 3 )
855
+ # Setup client server.
856
+ hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
857
+
858
+ root = nil
859
+
860
+ # Define project root, if it is explicitly defined.
861
+ if ENV['DIRU_ROOT']
862
+ root = ENV['DIRU_ROOT']
863
+ else
864
+ # First search for .diru_root_dir file.
865
+ begin
866
+ root = File.dirname( Diru.find_upper_file( '.diru_root_dir' ) )
867
+ rescue
868
+ root = nil
869
+ end
870
+ end
871
+
872
+ opts_json = ".diru.json"
873
+ opts_yaml = ".diru.yml"
874
+
875
+ opts_filename = nil
876
+ opts_file = nil
877
+
878
+ if root
879
+ if Opt['options'].given
880
+ opts_filename = Opt['options'].value
881
+ elsif ENV['DIRU_OPTS']
882
+ opts_filename = ENV['DIRU_OPTS']
883
+ elsif File.exists? "#{ENV['HOME']}/#{opts_json}"
884
+ opts_filename = "#{ENV['HOME']}/#{opts_json}"
885
+ elsif File.exists? "#{ENV['HOME']}/#{opts_yaml}"
886
+ opts_filename = "#{ENV['HOME']}/#{opts_yaml}"
887
+ else
888
+ opts_filename = nil
889
+ end
890
+ else
891
+ # No explicit root, hence derive from options file (if any).
892
+ begin
893
+ file = Diru.find_an_upper_file( [ opts_json, opts_yaml ] )
894
+ root = File.dirname( file )
895
+ opts_filename = file
896
+ rescue
897
+ Diru.error "Could not find user directory root!"
898
+ end
899
+ end
900
+
901
+ if opts_filename
902
+ case File.extname( opts_filename )
903
+ when ".json"; opts_file = DiruConfJson.new( opts_filename )
904
+ when ".yml"; opts_file = DiruConfYaml.new( opts_filename )
905
+ else raise RuntimeError, "Wrong Diru configuration file format (i.e. not json or yaml)!"
906
+ end
907
+ else
908
+ raise RuntimeError, "Missing configuration file!"
909
+ end
910
+
911
+ s_port = 0
912
+ cnt = 0
913
+ while ( s_port == 0 && cnt < try_cnt )
914
+ begin
915
+ s_port = hub.get_server( root, user, opts_file )
916
+ rescue
917
+ Diru.warn "Access to Hub failed!" if cnt >= 1
918
+ sleep( 1 )
919
+ end
920
+ cnt += 1
921
+ end
922
+
923
+ if s_port == 0
924
+ Diru.error "Could not start server!"
925
+ else
926
+ puts "Using server port: #{s_port}..."
927
+ end
928
+
929
+ end
930
+
931
+
822
932
  attr_reader :root
823
933
  attr_reader :user
824
934
 
@@ -833,6 +943,11 @@ class Service
833
943
  self
834
944
  end
835
945
 
946
+ # Response true (if alive).
947
+ def alive?
948
+ true
949
+ end
950
+
836
951
  # Kill service.
837
952
  def kill
838
953
  @search.kill
@@ -856,235 +971,6 @@ class Service
856
971
  end
857
972
 
858
973
 
859
- if Opt['template'].given
860
- puts %q{---
861
- hist: 20
862
- sync: 10
863
- dsync: 0
864
- favs:
865
- f: dir_0/dir_0_4/dir_0_4_0
866
- g: dir_1/dir_1_2
867
- peers:
868
- - - "(.*/dir_0/.*)/dir_0_2_0"
869
- - "\\1"
870
- - - "(.*/dir_0/.*)/dir_0_1_0"
871
- - "\\1/dir_0_1_1"
872
- }
873
- exit( false )
874
- end
875
-
876
-
877
- # Keep in sync with README.
878
- if Opt['cmddoc'].given
879
- STDERR.puts %q{
880
- Search commands:
881
-
882
- * "dr r" - change to Project root dir.
883
- * "dr r <dir>" - change to <dir> (somewhere) under Project root dir
884
- (glob).
885
- * "dr t <dir>" - change to <dir> (somewhere) under current dir (glob).
886
- * "dr e <dir>" - change to <dir> (somewhere) under Project root dir
887
- (regexp).
888
-
889
- Bookmark commands:
890
-
891
- * "dr b" - display bookmarks.
892
- * "dr b ." - add current dir to bookmarks.
893
- * "dr b !" - reset (clear) bookmarks.
894
- * "dr b s <file>" - store bookmarks to <file>.
895
- * "dr b l <file>" - load bookmarks from <file>.
896
- * "dr b d <num>" - delete bookmark with <num>.
897
- * "dr b <num>" - change dir to bookmark <num>.
898
-
899
- History commands:
900
-
901
- * "dr h" - display history.
902
- * "dr h ." - add current dir to history.
903
- * "dr h !" - reset (clear) history.
904
- * "dr h 0" - reference latest history item.
905
- * "dr h <num>" - change dir to history <num>.
906
-
907
- Scratch Pad commands:
908
-
909
- * "dr s ." - store current dir to Default Scratch Pad.
910
- * "dr s . <reg>" - store current dir to <reg> in Scratch Pad.
911
- * "dr s <dir>" - store <dir> to Default Scratch Pad.
912
- * "dr s <d> <r>" - store <dir> to <reg> in Scratch Pad.
913
- * "dr s" - change dir to Default Scratch Pad.
914
- * "dr s <reg>" - change dir to <reg> from Scratch Pad.
915
- * "dr s =" - display Scratch Pad content.
916
- * "dr s !" - reset (clear) Scratch Pad.
917
-
918
- Misc commands:
919
-
920
- * "dr p" - jump to peer dir, i.e. the peer of current (from options).
921
- * "dr c <cmd>" - issue RPC command to server (reset etc., see below).
922
- * "dr f" - list favorites dirs (from options).
923
- * "dr f <dir>" - change dir to favorite <dir>.
924
- * "dr d m <dir>" - make directory.
925
- * "dr d r <dir>" - remove directory.
926
- * "dr i" - show command info.
927
- * "dr <dir>" - change to given dir (must be under current).
928
- * "dr" - change to next "Left-over" directory.
929
-
930
- }
931
- exit( false )
932
- end
933
-
934
-
935
- hport = nil
936
- if Opt['hport'].given
937
- hport = Opt['hport'].value.to_i
938
- else
939
- hport = Diru::DIRU_HUB_PORT
940
- end
941
-
942
-
943
- if Opt['hub'].given
944
-
945
- # Hub:
946
- h = Hub.start( hport, !Opt['nodaemon'].given )
947
- exit( true )
948
- end
949
-
950
-
951
- if false
952
- # For hub maintenance (irb):
953
- require 'drb'
954
- hub = DRbObject.new( nil, "druby://localhost:41114" )
955
- hub.list_servers
956
- end
957
-
958
-
959
- if false
960
- # Test client
961
- require 'drb'
962
- @port = 41115
963
- @search = DRbObject.new( nil, "druby://localhost:#{@port}" )
964
- end
965
-
966
-
967
- if Opt['hkill'].given
968
- begin
969
- hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
970
- hub.kill
971
- rescue
972
- Diru.error "Could not kill Hub!"
973
- end
974
- exit( true )
975
- end
976
-
977
-
978
- if Opt['server'].given
979
-
980
- # Setup client server.
981
- hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
982
-
983
- root = nil
984
-
985
- # Define project root, if it is explicitly defined.
986
- if ENV['DIRU_ROOT']
987
- root = ENV['DIRU_ROOT']
988
- else
989
- # First search for .diru_root_dir file.
990
- begin
991
- root = File.dirname( Diru.find_upper_file( '.diru_root_dir' ) )
992
- rescue
993
- root = nil
994
- end
995
- end
996
-
997
- opts_json = ".diru.json"
998
- opts_yaml = ".diru.yml"
999
-
1000
- opts_filename = nil
1001
- opts_file = nil
1002
-
1003
- if root
1004
- if Opt['options'].given
1005
- opts_filename = Opt['options'].value
1006
- elsif ENV['DIRU_OPTS']
1007
- opts_filename = ENV['DIRU_OPTS']
1008
- elsif File.exists? "#{ENV['HOME']}/#{opts_json}"
1009
- opts_filename = "#{ENV['HOME']}/#{opts_json}"
1010
- elsif File.exists? "#{ENV['HOME']}/#{opts_yaml}"
1011
- opts_filename = "#{ENV['HOME']}/#{opts_yaml}"
1012
- else
1013
- opts_filename = nil
1014
- end
1015
- else
1016
- # No explicit root, hence derive from options file (if any).
1017
- begin
1018
- file = Diru.find_an_upper_file( [ opts_json, opts_yaml ] )
1019
- root = File.dirname( file )
1020
- opts_filename = file
1021
- rescue
1022
- Diru.error "Could not find user directory root!"
1023
- end
1024
- end
1025
-
1026
- if opts_filename
1027
- case File.extname( opts_filename )
1028
- when ".json"; opts_file = DiruConfJson.new( opts_filename )
1029
- when ".yml"; opts_file = DiruConfYaml.new( opts_filename )
1030
- else raise RuntimeError, "Wrong Diru configuration file format (i.e. not json or yaml)!"
1031
- end
1032
- else
1033
- raise RuntimeError, "Missing configuration file!"
1034
- end
1035
-
1036
- if Opt['server'].value.any?
1037
- user = Opt['server'].value[0]
1038
- else
1039
- user = ENV['USER']
1040
- end
1041
-
1042
- begin
1043
- s_port = hub.get_server( root, user, opts_file )
1044
- rescue
1045
- Diru.error "Access to Hub failed!"
1046
- end
1047
-
1048
- if s_port == 0
1049
- Diru.error "Could not start server!"
1050
- else
1051
- puts "Using server port: #{s_port}..."
1052
- end
1053
-
1054
- exit( true )
1055
- end
1056
-
1057
-
1058
- if Opt['kill'].given
1059
-
1060
- hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
1061
- port = Opt['kill'].value.to_i
1062
- begin
1063
- hub.kill_server port
1064
- rescue
1065
- Diru.error "Access to Hub failed!"
1066
- end
1067
-
1068
- exit( true )
1069
- end
1070
-
1071
-
1072
- if Opt['list'].given
1073
-
1074
- hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
1075
- begin
1076
- hub.list_servers.each do |i|
1077
- puts format( "%-12.d %-12s %s", i[0], i[2], i[1] )
1078
- end
1079
- rescue
1080
- Diru.error "Access to Hub failed!"
1081
- end
1082
-
1083
- exit( true )
1084
- end
1085
-
1086
-
1087
-
1088
974
  # ------------------------------------------------------------
1089
975
  # Client program.
1090
976
  # ------------------------------------------------------------
@@ -1261,6 +1147,29 @@ class Client
1261
1147
  fav_map( arg )
1262
1148
  end
1263
1149
 
1150
+ when 'l';
1151
+ if arg[0] == nil
1152
+ @search.lut.each do |k,v|
1153
+ STDERR.puts " #{k.to_s.ljust(16)} #{v}"
1154
+ end
1155
+ else
1156
+ if arg[0] == '!'
1157
+ if arg.length == 1
1158
+ @search.rlut
1159
+ else
1160
+ @search.rlut( arg[1] )
1161
+ end
1162
+ else
1163
+ if arg.length == 1
1164
+ val = @search.getlut( arg[0] )
1165
+ STDERR.puts val if val
1166
+ else
1167
+ @search.setlut( arg[0], arg[1] )
1168
+ end
1169
+ end
1170
+ end
1171
+ no_cd
1172
+
1264
1173
  when 'd';
1265
1174
  # Mkdir:
1266
1175
  # dr d m <dir>
@@ -1377,6 +1286,7 @@ class Client
1377
1286
  p - peer of current
1378
1287
  c - command (reset, doc etc.)
1379
1288
  f - favorites
1289
+ l - lookup key/value store
1380
1290
  d - directory mutation
1381
1291
  i - short info
1382
1292
  "
@@ -1434,6 +1344,218 @@ class Client
1434
1344
  end
1435
1345
 
1436
1346
 
1347
+
1348
+ # ------------------------------------------------------------
1349
+ # Server (and generic) actions.
1350
+ # ------------------------------------------------------------
1351
+
1352
+
1353
+ if Opt['template'].given
1354
+ puts %q{{
1355
+ "sync": 10,
1356
+ "dsync": 0,
1357
+ "hist": 20,
1358
+ "favs": {
1359
+ "f": "dir_0/dir_0_4/dir_0_4_0",
1360
+ "g": "dir_1/dir_1_2"
1361
+ },
1362
+ "peers": [
1363
+ [
1364
+ "(.*/dir_0/.*)/dir_0_2_0",
1365
+ "\\\\1"
1366
+ ],
1367
+ [
1368
+ "(.*/dir_0/.*)/dir_0_1_0",
1369
+ "\\\\1/dir_0_1_1"
1370
+ ]
1371
+ ]
1372
+ }
1373
+ }
1374
+ exit( false )
1375
+ end
1376
+
1377
+
1378
+ # Keep in sync with README.
1379
+ if Opt['cmddoc'].given
1380
+ STDERR.puts %q{
1381
+ Search commands:
1382
+
1383
+ dr r - change to Project root dir.
1384
+ dr r <dir> - change to <dir> (somewhere) under Project root dir
1385
+ (glob).
1386
+ dr t <dir> - change to <dir> (somewhere) under current dir (glob).
1387
+ dr e <dir> - change to <dir> (somewhere) under Project root dir
1388
+ (regexp).
1389
+
1390
+ Bookmark commands:
1391
+
1392
+ dr b - display bookmarks.
1393
+ dr b . - add current dir to bookmarks.
1394
+ dr b ! - reset (clear) bookmarks.
1395
+ dr b s <file> - store bookmarks to <file>.
1396
+ dr b l <file> - load bookmarks from <file>.
1397
+ dr b d <num> - delete bookmark with <num>.
1398
+ dr b <num> - change dir to bookmark <num>.
1399
+
1400
+ History commands:
1401
+
1402
+ dr h - display history.
1403
+ dr h . - add current dir to history.
1404
+ dr h ! - reset (clear) history.
1405
+ dr h 0 - reference latest history item.
1406
+ dr h <num> - change dir to history <num>.
1407
+
1408
+ Scratch Pad commands:
1409
+
1410
+ dr s . - store current dir to Default Scratch Pad.
1411
+ dr s . <reg> - store current dir to <reg> in Scratch Pad.
1412
+ dr s <dir> - store <dir> to Default Scratch Pad.
1413
+ dr s <d> <r> - store <dir> to <reg> in Scratch Pad.
1414
+ dr s - change dir to Default Scratch Pad.
1415
+ dr s <reg> - change dir to <reg> from Scratch Pad.
1416
+ dr s = - display Scratch Pad content.
1417
+ dr s ! - reset (clear) Scratch Pad.
1418
+
1419
+ Lookup commands:
1420
+
1421
+ dr l - list all lookup <key>/<v> pairs.
1422
+ dr ! - remove all keys.
1423
+ dr ! <key> - remove <key>.
1424
+ dr l <key> - lookup value for <key>.
1425
+ dr l <key> <v> - store value <v> for <key>.
1426
+
1427
+ Misc commands:
1428
+
1429
+ dr p - jump to peer dir, i.e. the peer of current (from options).
1430
+ dr c <cmd> - issue RPC command to server (reset etc., see below).
1431
+ dr f - list favorites dirs (from options).
1432
+ dr f <dir> - change dir to favorite <dir>.
1433
+ dr d m <dir> - make directory.
1434
+ dr d r <dir> - remove directory.
1435
+ dr i - show command info.
1436
+ dr <dir> - change to given dir (must be under current).
1437
+ dr - change to next "Left-over" directory.
1438
+
1439
+ }
1440
+ exit( false )
1441
+ end
1442
+
1443
+
1444
+ hport = nil
1445
+ if Opt['hport'].given
1446
+ hport = Opt['hport'].value.to_i
1447
+ else
1448
+ hport = Diru::DIRU_HUB_PORT
1449
+ end
1450
+
1451
+
1452
+ if Opt['hkill'].given
1453
+ begin
1454
+ hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
1455
+ hub.kill
1456
+ rescue
1457
+ Diru.error "Could not kill Hub!"
1458
+ end
1459
+ exit( true )
1460
+ end
1461
+
1462
+
1463
+ if Opt['kill'].given
1464
+
1465
+ hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
1466
+ port = Opt['kill'].value.to_i
1467
+ begin
1468
+ hub.kill_server port
1469
+ rescue
1470
+ Diru.error "Access to Hub failed!"
1471
+ end
1472
+
1473
+ exit( true )
1474
+ end
1475
+
1476
+
1477
+ if Opt['list'].given
1478
+
1479
+ hub = DRbObject.new( nil, "druby://localhost:#{hport}" )
1480
+ begin
1481
+ hub.list_servers.each do |i|
1482
+ puts format( "%-12.d %-12s %s", i[0], i[2], i[1] )
1483
+ end
1484
+ rescue
1485
+ Diru.error "Access to Hub failed!"
1486
+ end
1487
+
1488
+ exit( true )
1489
+ end
1490
+
1491
+
1492
+ if false
1493
+ # For hub maintenance (irb):
1494
+ require 'drb'
1495
+ hub = DRbObject.new( nil, "druby://localhost:41114" )
1496
+ hub.list_servers
1497
+ end
1498
+
1499
+
1500
+ if false
1501
+ # Test client:
1502
+ require 'drb'
1503
+ @port = 41115
1504
+ @search = DRbObject.new( nil, "druby://localhost:#{@port}" )
1505
+ end
1506
+
1507
+
1508
+ if Opt['hub'].given
1509
+
1510
+ # Start Hub.
1511
+ Hub.start( hport, !Opt['nodaemon'].given )
1512
+
1513
+ exit( true )
1514
+ end
1515
+
1516
+
1517
+ if Opt['server'].given
1518
+
1519
+ # Server options.
1520
+ if Opt['server'].value.any?
1521
+ user = Opt['server'].value[0]
1522
+ else
1523
+ user = ENV['USER']
1524
+ end
1525
+
1526
+ # Start service.
1527
+ Service.start( hport, user )
1528
+
1529
+ exit( true )
1530
+ end
1531
+
1532
+
1533
+
1534
+ if Opt['start'].given
1535
+
1536
+ # Start Hub.
1537
+ Hub.start( hport, !Opt['nodaemon'].given )
1538
+
1539
+ # Server options.
1540
+ if Opt['server'].value.any?
1541
+ user = Opt['server'].value[0]
1542
+ else
1543
+ user = ENV['USER']
1544
+ end
1545
+
1546
+ # Start server.
1547
+ Service.start( hport, user )
1548
+
1549
+ exit( true )
1550
+ end
1551
+
1552
+
1553
+
1554
+
1555
+ # ------------------------------------------------------------
1556
+ # Client actions.
1557
+ # ------------------------------------------------------------
1558
+
1437
1559
  if Opt['port'].given
1438
1560
  port = Opt['port'].value.to_i
1439
1561
  elsif ENV['DIRU_PORT']
@@ -1,5 +1,5 @@
1
1
  module Diru
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  def Diru.version
4
4
  Diru::VERSION
5
5
  end
@@ -273,6 +273,7 @@ Diru Warning: Dir not found!
273
273
  p - peer of current
274
274
  c - command (reset, doc etc.)
275
275
  f - favorites
276
+ l - lookup key/value store
276
277
  d - directory mutation
277
278
  i - short info
278
279
 
@@ -347,6 +348,7 @@ Diru Warning: Dir not found!
347
348
  p - peer of current
348
349
  c - command (reset, doc etc.)
349
350
  f - favorites
351
+ l - lookup key/value store
350
352
  d - directory mutation
351
353
  i - short info
352
354
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diru
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tero Isannainen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-24 00:00:00.000000000 Z
11
+ date: 2019-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: como
@@ -27,7 +27,7 @@ dependencies:
27
27
  description: |-
28
28
  Diru is a Change Directory (cd) utility for
29
29
  augmenting Unix Shell functionality. Diru makes it easy and efficient
30
- to jump around in Project's directories. Diru uses server/client
30
+ to jump around in Project's directories. Diru uses client/server
31
31
  architecture, which enables sharing of directory info and state
32
32
  between terminal sessions.
33
33
 
@@ -37,7 +37,7 @@ description: |-
37
37
  concurrently.
38
38
 
39
39
  Client queries directory info from Server and directory change is
40
- pushed to Shell in order to change the current directory within
40
+ pushed to Shell in order to change the current directory within the
41
41
  Shell.
42
42
  email: tero.isannainen@gmail.com
43
43
  executables: