-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtomohara-aliases.bash
executable file
·3307 lines (3098 loc) · 145 KB
/
tomohara-aliases.bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#! /usr/bin/env bash
# -*- coding: utf-8 -*-
#
# tomohara-aliases.bash: Tom's Initialization file for use with bash,
# using suppoting scripts from
# http://www.cs.nmsu.edu/~tomohara/useful-scripts/tpo-useful-scripts.tar.gz
#
# This is in the process of being re-organized to make it easier to test and to
# isolate the isolate the stuff specific to my workflow (i.e., "idiosyncratic").
#
# NOTES:
# - *** This is a pruned down version of do_setup.bash. It should be renamed to tohara-setup.bash as it includes more than just just aliases!
# - ** Put overly large function definitions into scripts (e.g., prepare-find-files-here, hg-pull-and-update, show-unicode-code-info-aux, and init-condaN)!
# These can be identified as follows:
# $ grep -A20 ^function ~/bin/tomohara-aliases.bash | perl -pe 's/^function/\n$&/;' | egrep -v '^(#|alias)' | para-len | sort -rn | less
# - * add alias for resolving command binary with fallback to "command name" (e.g., resolve-command ls => /bin/ls or "command ls").
# - * Drop () from function definition, as optional!
# For example,
# Function definition syntax:
# [ function ] name () { command-list; }
# where () is optional if 'function' given
# Therefore,
# function fubar1 () { 666; };
# function fubar2 { 666; };
# set | grep -A3 ^fubar[12]
# =>
# fubar1 ()
# {
# echo 666
# }
# fubar2 ()
# {
# echo 666
# }
#
# - Obsolete old code flagged with '## OLD': either older definition
# or no longer used).
# - Misc. old code flagged with '## MISC' (e.g., old but potentially useful).
# - Exceptionally idiosyncratic aliases are flagged with '## TOM-IDIOSYNCRATIC'. (These
# should be considered as experimental.)
# - See extra-tomohara-aliases.bash for aliases for adhoc aliases (e.g., not
# used on a regular basis and/or special purpose).
# - This gets invoked from $HOME/.bashrc.local.
# - from bash manual:
# Special Parameters
# ...
# @ Expands to the positional parameters, starting from
# one. When the expansion occurs within double
# quotes, each parameter expands as a separate word.
# That is, `` $@'' is equivalent to ``$1'' ``$2'' ...
# When there are no positional parameters, ``$@'' and
# $@ expand to nothing (i.e., they are removed).
# - $* is like $@ except that it accounts for inter-field separator (IFS)
# - CygWin takes very long to process this script so certain sections
# are not evaluated if under arahomot; TODO: check for CygWin flag.
# - Variables in function definitions should be declared local to avoid subtle problems
# due to retained values.
# - Alias definition syntax:
# alias [-p] [name[=value] ...]
# - from bash man page:
# When bash is invoked as an interactive login shell, it
# first reads and executes commands from the file /etc/pro-
# file, if that file exists. After reading that file, it
# looks for ~/.bash_profile, ~/.bash_login, and ~/.profile,
# in that order, and reads and executes commands from the
# first one that exists and is readable.
# ...
# When an interactive shell that is not a login shell is
# started, bash reads and executes commands from ~/.bashrc,
# if that file exists.
# ...
# - Commonly used Bash features which might not be familiar:
# -- $(...) is used in place of `...` (as the backtick is escape for GNU screen terminal shell utility.
# -- 'command cmd' invoke specifed Unix cmd, not aliases/functions.
# -- 'builtin cmd' likewise invokes shell builtin cmd, not aliases/functions.
# -- "$@" which argument list with each argument quoted.
# -- 'ENV_VAR=value command ...' runs command with temp. environment setting.
# - Likewise commonly used Unix features which might not be familiar:
# -- 'realpath file' returns full path for file with relative path.
# - Selectively ignores following shellcheck warnings:
# -- SC2016: Expressions don't expand in single quotes
# -- SC2046: Quote this to prevent word splitting
# -- SC2086: Double quote to prevent globbing and word splitting.
# -- SC2155: Declare and assign separately to avoid masking return values
# -- SC2139: This expands when defined, not when used. Consider escaping.
# -- SC2206: Quote to prevent word splitting/globbing
# -- SC2116: Useless echo?
#
# TODO:
# - ***** Put work-specific stuff in separate file!"
# - **** Add EX-bases tests for all numeric aliases!
# - ***** Fix problems noted by shellcheck (and rework false positives)!.
# - *** Indent [maldito] shell-check blocks.
# - ** Add macros to provide cribsheet on usage!
# - *** Purge way-old stuff (e.g., lynx related)!
# - *** Use check_usage for usage statements.
# - ** Add option to move alias not to put files in subdirectory of target directory. That is, the move command aborts rather than doing following: 'move sub-dir target-dir' ==> target-dir/sub-dir/sub-dir).
# - ** Minimize overriding commands like 'cd' and 'script' to avoid confusion.
# - ** Likewise non-standard usages for variables like 'PS1' (e.g., via 'PS_symbol').
# - * Drop support for solaris and remove BAREBONES_HOST support.
# - Get rid of old-work junk (e.g., Intemass, Juju, and JSL)!
# - Replace backquote evaluation (`...`) with $(...)
# - ** Fix the many cracks that fell through alias categorization (alias/function grouping???).
# - convert $* to "$@" throughout, as appropriate
# - add more structure and decompose into helper scripts (e.g, wordnet aliases)
# - use dashes instead of underscores in scripts as well as macros
# - decompose into do-cs-setup.bash do-arahomot-setup.bash, etc.
# - add more optional sections (as with 'if [ "$HOSTNAME" != "arahomot" ]; ...'
# - replace '-' macro suffix (eg, 'gr-') with something more uniformative (eg, '-alt')
# - create function for recreating local directories (e.g., ~/info) assumed by do-setup scripts (e.g., do_setup.bash)
# - Remove () from function definitions.
# - Add error checking in functions for unspecified arguments.
# - Make sure all function variables use local.
# - Add upcase alias (perl -pe 's/(.*)/\U$1\e/g;')
# - Make sure functions don't refer to undefined macros (e.g., defined later).
# - Main environment variables (e.g., HOST, DEFAULT_HOST, etc.)!
# DEFAULT_HOST: (remote) hostname which gets omitted from xterm title
# MY_GREP_OPTIONS: options for grep command (e.g., "-n -d skip -s")
# TOM_BIN: directory for shell scripts
# TODO: the rest
# - Miscellaneous environment variables:
# GTAR: gnu version of tar (n.b., same as tar under Linux)
# NICE: command for running another under nice priority
# PYTHON: command for runnng python (e.g., "nice -19 /usr/bin/time python -u")
# SORT_COL2: key specification for sort (e.g., "--key=2")
# TPO_SSH_KEY: path to private SSH key
# - Make sections more apparent and easier to grep (e.g., use Xyz settings (or Xyz Stuff, along
# with section dividers).
# - Replace '/bin/cmd ...' with 'command cmd ...' in aliases.
#
# For debugging: Uncomment the following line(s)
## DEBUG: echo in tomohara-aliases.bash 1>&2
## DEBUG: set -o xtrace
#...............................................................................
# Bash wrappers
# Conditional environment variable setting
# Format: cond-export VAR1 VALUE1 [VAR2 VALUE2] ...
# EX: export FU="bar"; conditional-export FU baz; echo $FU => bar
#
function conditional-export () {
local var value
local args
while [ "$1" != "" ]; do
var="$1" value="$2";
## DEBUG: echo "value for env. var. $var: $(printenv "$var")"
if [ "$(printenv "$var")" == "" ]; then
# Ignores SC1066: Don't use $ on the left side of assignments
# shellcheck disable=SC1066,SC2046,SC2086
export $var="$value"
fi
args="$*"
shift 2
if [ "$args" = "$*" ]; then
echo "Error: Unexpected value in conditional-export (var='$var'; val='$value')"
return
fi
done
}
#
alias conditional-setenv='conditional-export'
alias cond-export='conditional-export'
# TODO: drop following after all do_setup.bash settings moved here
alias cond-setenv='conditional-export'
# For debugging: Uncomment the following to display the environment variables (TODO: rework via startup-trace).
## printenv.sh
# alias-fn(name, statement, ...): define NAME alias via function def w/ STATEMENT ...
# NOTE:
# - Variable intended for run-time evaluation should be passed inside a single quoted string (or escaped with \)
# - This is so that the alias becomes a "first class" citizen, such as allowing for
# environment variables to be set as in 'alias-fn echo-ENV1 'echo "$ENV1"'; ENV1=one echo-ENV1
# - Use dummy command if a background command is invoked: gotta hate Bash!
# ex: alias-fn eyes 'xeyes & true'
# - General version as replacement for complex aliases with multiple commands
##
# ex: alias-fn trace-PS1 'echo \$PS1="$PS1" 1>&2'
# TODO: fix problem with embedded invocations (see em-adhoc-notes below)
function alias-fn {
local alias="$1"
shift
local body="$*"
eval "function $alias { $body; }"
}
# simple-alias-fn(name, command): variant that takes command and appends "$@"
# ex: simple-alias-fn git-next-checkin 'invoke-alt-checkin'
# Note: this is streamlined version of alias-fn intended as replacement for 'alias name=command' usages
function simple-alias-fn {
if [ "$3" != "" ]; then
echo "usage: simple-alias-fn alias command"
echo "note: '\$\@' gets appended to command"
return
fi
local alias="$1"
local command="$2"
# note:
eval "function $alias { $command" '"$@"' "; }"
}
# deprecated-alias-fn: version of simple-alias-fn that issues deprecated warning
# TODO3: seee if it can be defined via simple-alias-fn
function deprecated-alias-fn {
local alias="$1"
local command="$2"
eval "function $alias { echo 'Warning: deprecated alias: $alias' 1>&2; $command" '"$@"' "; }"
}
#................................................................................
# General environment settings
## TOM-IDIOSYNCRATIC
cond-export DEBUG_LEVEL 3
#...............................................................................
# Directory for Tom O'Hara's scripts, defaulting to /home/tomohara if available
# otherwise $HOME/bin
## TOM-IDIOSYNCRATIC
## DEBUG:
# Note: ${BASH_SOURCE[0]}" is the scirpt being sourced. The array itself gives
# the source files for all functions on the execution call stack.
# See https://stackoverflow.com/questions/35006457/choosing-between-0-and-bash-source.
alias_source_dir="$(dirname "${BASH_SOURCE[0]:-$0}")"
cond-export TOM_DIR "$alias_source_dir/.."
if [ ! -d "$TOM_DIR" ]; then
echo "Warning unable to resolve TOM_DIR; using $HOME" 1>&2
export TOM_DIR="$HOME";
fi
#
master_alias_script="all-tomohara-aliases-etc.bash"
cond-export TOM_BIN "$alias_source_dir"
if [ ! -e "$TOM_BIN/$master_alias_script" ]; then
echo "Warning: Unable to find $master_alias_script in Tom's bin directory ()" 1>&2
fi
alias tomohara-setup='source $TOM_BIN/$master_alias_script'
# Alias for startup-script tracing via startup-trace function
if [ ! -e "$HOME/temp" ]; then
echo "WARNING: creating $HOME/temp for startup script logs"
mkdir "$HOME/temp"
fi
#
# Define simple version of startup tracing
function startup-trace () { if [ "$STARTUP_TRACING" = "1" ]; then echo "$@" "[$HOSTNAME $(date)]" >> "$HOME/temp/.startup-$HOSTNAME-$$.log"; fi; }
# conditional-source(filename): source in bash commands from filename if exists
function conditional-source () { if [ -e "$1" ]; then source "$1"; else echo "Warning: bash script file not found (so not sourced):"; echo " $1"; fi; }
function quiet-conditional-source { source "$@" > /dev/null 2>&1; }
#
# Enable full-blown startup tracing if evailable
# note: kept separate for use in other scripts
conditional-source "$TOM_BIN/startup-tracing.bash"
#
alias trace='startup-trace'
alias enable-startup-tracing='export STARTUP_TRACING=1'
alias disable-startup-tracing='export STARTUP_TRACING=0'
alias enable-console-tracing='export CONSOLE_TRACING=1'
alias disable-console-tracing='export CONSOLE_TRACING=0'
# Helper functions (along with aliases and variables)
#
# space-check(arg): ensures ARG has no embedded spaces (and no other arguments)
function space-check() {
if [ "$2" != "" ]; then
echo "Error: space-check accepts just 1 arg; extraneous arg follows: $2"
fi
case "$1" in *\ *) echo "Error: argument should not contain spaces: $1";; esac
}
# downcase-stdin(): convert STDIN to lowercase
# downcase-text(text, ...): downcase TEXT
# EX: echo "Tomás" | downcase-stdin => "tomás"
## BAD: function downcase-stdin() { perl -pe 's/.*/\L$&/;'; }
## TODO:
## alias perl-utf8="perl -e \"use open ':std', ':encoding(UTF-8)'\""
## function downcase-stdin() { perl-utf8 -pe 's/.*/\L$&/;'; }
function downcase-stdin { perl -pe "use open ':std', ':encoding(UTF-8)'; s/.*/\L$&/;"; }
function downcase-text { echo "$@" | downcase-stdin; }
# todays-date(): outputs date in format DDmmmYY (e.g., 22apr20)
## TODO: drop leading digits in day of month
## NOTE: keep in synch with common.perl get_file_ddmmmyy and .emacs edit-adhoc-notes-file
function todays-date { date '+%d%b%y' | downcase-stdin; }
# todays-date-mmmYY(): date in format mmmYY (e.g., sep20)
function todays-date-mmmYY { todays-date | perl -pe 's/^\d\d//;'; }
# hoy: alternative to todays-date
alias hoy=todays-date
hoy=$(todays-date)
# Note: version so Spanish not used in note files
# TODO: punt on tab-completion (i.e., TODAY => today)???
alias TODAY=todays-date
alias date-central='TZ="America/Chicago" date'
## TOM-IDIOSYNCRATIC
# em-adhoc-notes(): edit adhoc notes file using format _{dir}-notes-{host}-{date} (e.g., _bin-notes-reempl-may22.txt)
## Lorenzo review: what's the purpose of keeping the old versions?
## BAD: alias-fn em-adhoc-notes 'emacs-tpo _${HOST_NICKNAME:misc}-adhoc-notes-$(todays-date-mmmYY).txt'
function em-adhoc-notes {
emacs-tpo "$(downcase-text "$(basename "$PWD")-notes-${HOST_NICKNAME:tpo-host}-$(todays-date-mmmYY).txt")";
}
alias T='TODAY'
# update-today-vars() & todays-update: update the various today-related variables
# aside: descriptive name for function and convenience alias (tab-completion)
# TODO: try for cron-like bash function to enable such updates automatically
function update-today-vars {
TODAY=$(todays-date)
T=$TODAY
}
update-today-vars
alias todays-update='update-today-vars'
#
# reference-variable(var, ...): use to mark VAR as used in order to silence bash liners like shell check (e.g., for variables only used interactively)
# usage: reference-variable "$var1, ..."
# TODO: figure out way to do without quotes (e.g., to avoid SC2086: Double quote to prevent globbing ...)
function reference-variable { true; }
## OLD: reference-variable "$hoy, $T"
## BAD: reference-variable $hoy, $T
reference-variable "$hoy $T"
# Alias creation helper(s)
# Note: does no-op so that status set to 0 for sake of tests/test_tomohara-aliases.bash setup
# TODO: use more explicit way to set status
## TODO: function quiet-unalias { unalias "$@" 2> /dev/null; echo > /dev/null; }
function quiet-unalias {
## HACK: do nothing if running under bats-core
if [ "$BATS_TEST_FILENAME" != "" ]; then
if [ "$BATCH_MODE" != "1" ]; then
echo "Ignoring unalias over $* for sake of bats"
fi
return
fi
unalias "$@" 2> /dev/null || true;
}
# Bash customizations (e.g., no beep)
# via https://www.gnu.org/software/bash/manual/bash.html
# - If the histappend shell option is set (see Bash Builtins), the lines are
# appended to the history file, otherwise the history file is overwritten.
# - HISTCONTROL
# ... ‘ignoredups’ causes lines which match the previous history entry to not
# be saved. .... ‘erasedups’ causes all previous lines matching the
# current line to be removed from the history list before that line is saved.
# - HISTSIZE: maximum number of commands to remember ... less than zero [means] every
# command [is] saved ... default value [is] 500...
# - HISTFILESIZE: maximum number of lines contained in the history file.
# TODO: do more excerpting or just summarize above.
set bell-style none
export HISTCONTROL=ignoredups
export HISTTIMEFORMAT='[%F %T] '
# Ensure that the history files are merged (n.b., timestamping required for
# proper sequencing of entries from different shell windows).
set histappend
# note: following are 50x the defaults
## BAD:
## export HISTSIZE=50000
## export HISTFILESIZE=100000
export HISTSIZE=25000
export HISTFILESIZE=32767
#
# Note: bash setting(s) in ~/.bash_profile
# format: shopt [-s | -u] optionname
# where -s to sets and -u unsets
# shopt -s nocaseglob # ignore case in filename glob patterns
#
# Ignore case in pattern matching
shopt -s nocasematch
#-------------------------------------------------------------------------------
trace do_setup.bash invocation
# Get initital settings from ~/bin/do_setup.bash
if [ -e "$TOM_BIN/do_setup.bash" ]; then source "$TOM_BIN/do_setup.bash"; fi
#-------------------------------------------------------------------------------
trace 'in tomohara-aliases.bash'
# # HACK: load in older tpo-setup.bash
# conditional-source $TOM_BIN/tpo-setup.bash
# under-macos() => boolean: whether running under maldito macintosh
# EX: (under-macos; wc -l /vmlinuz 2> /dev/null) =/=> $'0\n1'
function under-macos {
local under_mac=0
if [[ "$OSTYPE" =~ darwin.* ]]; then under_mac=1; fi
## TODO: return $under_mac
echo "$under_mac"
}
function under-linux {
local under_linux=0
if [[ "$OSTYPE" =~ linux.* ]]; then under_linux=1; fi
## TODO: return $under_linux
echo "$under_linux"
}
# Settings for less command
# LESS="-cFIX-P--Less-- ?f%f:(stdin). ?e(END):?pb(%pb\%) ?m(%i of %m)..%t"
#
# less options:
# -c full screen repaints to be painted from the top line down
# -F automatically exit if the entire file can be displayed on first screen
# -I searches ignore case even if the pattern contains uppercase letters
# -S Causes lines longer than the screen width to be chopped
# -X Disables sending the termcap initialization and deinitialization
# -P changes the prompt
# to override on command line
# -+<option> ex: -+F
#
export LESS="-cFIX-P--Less-- ?f%f:(stdin). ?e(END):?pb(%pb\%) ?m(%i of %m)..%t"
# Disables full-screen repaints under minimal-installation hosts (e.g., Beowolf nodes)
if [ "$BAREBONES_HOST" = "1" ]; then export LESS="-cIX-P--Less-- ?f%f:(stdin). ?e(END):?pb(%pb\%) ?m(%i of %m)..%t"; fi
export PAGER=less
export PAGER_CHOPPED="less -S"
export PAGER_NOEXIT="less -+F"
function zless () { zcat "$@" | $PAGER; }
#
# zhead(file, head-opts)
function zhead () {
local file="$1"
shift
zcat "$file" | head "$@"
}
alias less-='$PAGER_NOEXIT'
alias less-clipped='$PAGER_NOEXIT -S'
alias less-tail='$PAGER_NOEXIT +G'
alias less-tail-clipped='$PAGER_NOEXIT +G -S'
alias ltc=less-tail-clipped
export ZPAGER=zless
#-------------------------------------------------------------------------------
trace start of main settings
# Path settings
# TODO: define a function for removing duplicates from the PATH while
# preserving the order
function show-path-dir () { (echo "${1}:"; printenv "$1" | perl -pe "s/:/\n/g;") | $PAGER; }
alias show-path='show-path-dir PATH'
# append-path(path): appends PATH to environment variable unless already there
## TODO: function in-path { local path=$(tr ":" "\n" | $GREP "^$1$$"); return ($path != ""); }
# TODO: add force argument to ensure last (or first)
function append-path () { if [[ ! (($PATH =~ ^$1:) || ($PATH =~ :$1:) || ($PATH =~ :$1$)) ]]; then export PATH="${PATH}:$1"; fi }
function append-path-warn {
if [ ! -e "$1" ]; then
echo "Warning: append-path non-existent: $1" 1>&2
fi
append-path "$1";
}
#
function append-path-force () { export PATH="${PATH}:$1"; }
function prepend-path-force () { export PATH="$1:${PATH}"; }
alias prepend-path=prepend-path-force
# TODO: rework append-/prepend-path and python variants via generic helper
function append-python-path () { export PYTHONPATH=${PYTHONPATH}:"$1"; }
function prepend-python-path () { export PYTHONPATH="$1":${PYTHONPATH}; }
#-------------------------------------------------------------------------------
# Bash stuff (settings, etc.)
#
# FIGNORE: A colon-separated list of suffixes to ignore when performing filename completion ("tab completion")
export FIGNORE=".o:.fasl:.fas:.lib"
## TEST: export FIGNORE=".o:.fasl:.fas:.lib:.log"
## TODO: figure out how to exlcude .log for executable-tab-expansion (e.g., first position)
export FIGNORE=".o:.fasl:.fas:.lib"
set -o noclobber
#
# case-insensitive file glob
shopt -s nocaseglob
# note: add following to your .inputrc for case-insenstive tab completion
# set completion-ignore-case on
#
# MAILCHECK: Specifies how often (in seconds) bash checks for mail.
# ... If this variable is unset, the shell disables mail checking.
unset MAILCHECK
#
# Make sure tab completion not escaped for directory names
# Stupid bash developers: dropped without explicit warning!
## shopt -s direxpand
# MAIL If this parameter is set to a file name and the MAILPATH variable is not
# set, bash informs the user of the arrival of mail in the specified file.
unset MAIL
# Unix environ stuff
# Note:
# - TEMP is private temp dir (e.g., ~/temp); TMP is system temp dir (e.g., /tmp)
# TODO: Put settings in .bashrc, so that trace could use TEMP.
cond-export TEMP "$HOME/temp"
## HACK: don't allow /tmp for TMP
## TODO1: move TMP, etc. into tomohara-settings.bash
if [ "$TMP" = "/tmp" ]; then unset TMP; fi
cond-export TMP "$TEMP/tmp"
cond-export TMPDIR "$TMP"
mkdir -p "$TEMP" "$TMP" "$TMPDIR"
# NOTE: LINE and COLUMNS are in support of ps_sort.perl and h (history).
# They get reset via resize.
cond-export LINES 52
cond-export COLUMNS 80
#
# NOTE: resize used to set LINES below
alias run-csh='export USE_CSH=1; csh; export USE_CSH=0'
# Note: support for prompt prefix
# reset-prompt(symbol): resets PS1 to PS_symbol, optionally changed to symbol
# If symbol is empty, then DEFAULT_PS_SYMBOL is used.
# This could be a no-op if PS1 already is based on PS_symbol,
# ex: reset-prompt '§' # section sign [U+00A7]
# TODO: document PSn usage (e.g., Bash manual excerpt)
## TEST
## # PS_prefix should be defined in host-specific file (e.g., ~/.bashrc.<nickname>)
## # elsewhere: export PS_prefix="T "
## alias reset-prompt='export PS1="$PS_prefix""$ "'
# Note: PS_symbol defines the prompt symbol (e.g., '$' vs. '§' [U+00A7])
# example override (from .bashrc):
# export PS_symbol="¢" # cent sign (U+00A2)
## TODO: resolve interaction among 'reset-prompt', 'script' and 'add-conda-env-to-xterm-title' (see anacdonda-aliases.bash for latter)
cond-export PS_symbol '$'
function reset-prompt {
## DEBUG: echo "reset-prompt" "$@"
local new_PS_symbol="$*"
## OLD:
if [ "$new_PS_symbol" = "" ]; then new_PS_symbol="${DEFAULT_PS_SYMBOL:-$PS_symbol}"; fi
# Do nothing if empty
if [ "$new_PS_symbol" = "" ]; then return; fi
## TODO: if [ "$new_PS_symbol" = "" ]; then echo $'Usage: reset-prompt symbol\nex: reset-prompt §"\n'; return; fi
## TODO: add options to reset PS1 and to list good symbols for prompts
# Make the change
## DEBUG: echo "reset-prompt: 1. PS1='$PS1' old_PS_symbol='$old_PS_symbol' PS_symbol='$new_PS_symbol'"
export PS_symbol="$new_PS_symbol";
export PS1="$PS_symbol "
## DEBUG: echo "reset-prompt: 2. PS1='$PS1' old_PS_symbol='$old_PS_symbol' PS_symbol='$new_PS_symbol'"
# Update xterm title
set-title-to-current-dir;
## DEBUG: echo "reset-prompt: 3. PS1='$PS1' old_PS_symbol='$old_PS_symbol' PS_symbol='$new_PS_symbol'"
}
alias reset-prompt-root='reset-prompt "#"'
alias root-prompt=reset-prompt-root
alias reset-prompt-dollar='reset-prompt "\$"'
{
# shellcheck disable=SC2139
alias reset-prompt-default="reset-prompt '$PS_symbol'"
## Lorenzo review: same code marked as OLD 3 lines above
}
## TODO: alias reset-prompt-default='reset-prompt "\$PS_symbol"'
# rehash(): reset locations for programs
alias rehash='hash -l'
#
# check_usage(arg, help): shows HELP if ARG --help or empty, setting status true (0) if displayed
# sample: check_usage "$1" $'usage: munge filename\nexample: munge /etc/password' && return
function check_usage {
local expected_arg="$1"
local usage_text="$2"
if [[ ("$expected_arg" == "--help") || ("$expected_arg" == "") ]]; then
echo "$usage_text"
true
else
false
fi
}
#-------------------------------------------------------------------------------
# More misc stuff
## TOM-IDIOSYNCRATIC
# reset CDPATH to just current directory
export CDPATH=.
# flag for turning off GNOME, which can be flakey at times
# See xterm.sh (e.g., gnome-terminal).
export USE_GNOME=1
# General Settings for my scripts
export PRECISION=3
alias debug-on='export DEBUG_LEVEL=3'
if [ "$PERLLIB" = "" ]; then PERLLIB="."; else PERLLIB="$PERLLIB:."; fi
# NOTE: perl uses architecture-specific subdirectories under PERLLIB
export PERLLIB="$TOM_BIN:$PERLLIB:$HOME/perl/lib/perl5/site_perl/5.8"
# HACK: not all cygwin directories being recognized
export PERLLIB="$HOME/perl/lib/perl5/5.16:$HOME/perl/lib/perl5/5.16/vender_perl:$PERLLIB"
# perl-(): perl with following options: -S use path; -s enable switches (-x=v); -w show warnings;
# See perlrun manpage.
# TODO4: rename perl- to perl-usual???
alias perl-='perl -Ssw'
## Lorenzo review: should change this to perl-alt following TODO's
## TODO: function alias-perl { DURING_ALIAS=1 perl "$@"; }
# alias-perl(): perl with DURING_ALIAS defined (n.b., avoids excess tracing; see common.perl)
## NOTE: using perl.sh in alias leads to problems under Github workflows
## BAD:
alias alias-perl='DURING_ALIAS=1 DEBUG_LEVEL=$ALIAS_DEBUG_LEVEL perl -Ssw'
## TODO: alias alias-perl='DURING_ALIAS=1 perl.sh -Ssw'
## TODO?
## function alias-perl {
## DURING_ALIAS=1 env perl --Sw "eval $*";
## }
#
# alias-python: python invocation for using in aliases
# note: avoids excess tracing; see debug.py and main.py
alias alias-python='DURING_ALIAS=1 DEBUG_LEVEL=$ALIAS_DEBUG_LEVEL python3'
#
export MANPATH="$HOME/perl/share/man/man1:$MANPATH"
append-path "$HOME/perl/bin"
# Note: TIME is used for changing output format, so TIME_CMD used instead.
# TODO: Do check for environment variable overlap (as with DEBUG_LEVEL clash with software
# used at Convera).
## BAD: export TIME_CMD="command time"
# note: command is a binary under MacOs but just a shell builtin under Linux
export TIME_CMD="command time"
if [ "$(which "command" 2> /dev/null)" == "" ]; then
export TIME_CMD=/usr/bin/time
fi
export PERL="$NICE $TIME_CMD perl -Ssw"
# Terminal window title
alias set-xterm-title='set_xterm_title.bash'
alias set-xterm-window='set-xterm-title'
# Set the title for the current xterm, unless if not running X
# set-title-to-current-dir(): use $PWD with ~ un-expansion for xterm title
function set-title-to-current-dir () {
local dir
dir=$(basename "$PWD");
## TODO: local pwd="${PWD/$HOME/~}"
local pwd
pwd="$(echo "$PWD" | perl -pe "s@$HOME@~@;")"
local other_info="";
if [ "$CLEARCASE_ROOT" != "" ]; then other_info="; $other_info cc=$CLEARCASE_ROOT"; fi
set-xterm-window "$dir [$pwd]$other_info";
## Note: until VM setup for current client, the symbol is put before the directory basename.
## TEST: set-xterm-window "$PS_symbol $dir [$pwd]$other_info";
## TODO: set-xterm-window "$dir [$PS_symbol$pwd]$other_info";
}
if [[ ("$TERM" = "xterm") || ("$TERM" = "cygwin") ]]; then set-title-to-current-dir; fi
#
alias reset-xterm-title='set-xterm-window "$HOSTNAME $PWD"'
# alt-xterm-title([prefix=alt]): change xterm title to PREFIX DIR-BASENAME [PWD]
function alt-xterm-title() {
local dir
local prefix="$1"
if [ "$prefix" = "" ]; then prefix="alt"; fi
dir=$(basename "$PWD")
set-xterm-window "$prefix: $dir [$PWD]";
}
# TODO: see if DEFAULT_HOST used outside of xterm title
alias set-xterm-default-host='export DEFAULT_HOST=n/a; cd .'
alias gterm=gnome-terminal
# background-app(app, arg1, ...): runs APP in background with ARG1, ...
# note: helper for alias so that arguments can be added by user (e.g., --help)
function background-app () { "$@" & }
alias gdisk-mgr='background-app gnome-disks'
# Set file creation permission mask to enable RWX for user & group and none for others
# NOTE:
# - X needed in case directories created (or program files)
# - usage: umask ugo -or- umask symbolic-mode
#
# NOTE: umask is getting set to 0002 with above
#
## TODO: umask ug=rwx,o=r
# Settings for the Language Toolkit that comes with Open Office
cond-export LANGUAGE_TOOL_HOME "$TOM_DIR/programs/java/LanguageTool-2.1"
#------------------------------------------------------------------------
# Shell aliases for overriding commands, etc
#
trace alias overrides
# Command overrides for cd, etc. that set the xterm title to the current directory
# TODO: use alias's instead so that the same name can be used as the command
# NOTES:
#
# - (from bash manual) There is no mechanism for using arguments in
# the replacement text, as in csh. If arguments are needed, a shell
# function should be used.
#
# This is conditioned upon not running under emacs, so that the escape
# sequence doesn't end up in the buffer.
#
if [ "$UNDER_EMACS" != "1" ]; then
function cd () { builtin cd "$@"; set-title-to-current-dir; }
function pushd () { builtin pushd "$@"; set-title-to-current-dir; }
function popd () { builtin popd; set-title-to-current-dir; }
fi
alias chdir='cd'
# cd-realdir(dir): change into the real path for DIR
# cd-this-realdir: ditto for current directory
function cd-realdir {
local dir="$1";
if [ "$dir" = "" ]; then dir=.; fi;
# note: cd/pwd used so that xterm updated
cd "$(realpath "$dir")";
pwd;
}
alias cd-this-realdir='cd-realdir .'
# shellcheck disable=SC2016
alias-fn pushd-this-realdir 'pushd "$(realpath ".")"'
# pushd-q, popd-q: quiet versions of pushd and popd
#
function pushd-q () { builtin pushd "$@" >| /dev/null; }
function popd-q () { builtin popd >| /dev/null; }
#
# Command overrides for moving and copying files
# NOTE: -p option of cp (i.e., --preserve "preserve file attributes if possible")
# leads to problems when copying files owner by others (although group writable)
# cp: preserving times for /usr/local/httpd/internal/cgi-bin/phone-list: Operation not permitted
# - other options for cp, mv, and rm: -i interactive; and -v verbose.
other_file_args="-v"
if [ "$OSTYPE" = "solaris" ]; then other_file_args=""; fi
## NOTE: Unfortunately clear clobbers the terminal scrollback buffer.
## via https://askubuntu.com/questions/792453/how-to-stop-clear-from-clearing-scrollback-buffer:
## type CTRL+L instead of clear
## TAKE1: alias cls="printf '\33[H\33[2J'"
## where \33 is octal code for Escape (i.e., 0x1B)
## TAKE2
alias clear="echo 'use cls instead (or command clear)'"
alias cls="command clear -x"
{
# TODO: see if this is a shellcheck bug
# SC2034: MV appears unused. Verify it or export it.
# shellcheck disable=SC2034
MV="command mv -i $other_file_args"
}
alias mv='$MV'
alias move='mv'
alias move-force='move -f'
# TODO: make sure symbolic links are copied as-is (ie, not dereferenced)
CP="command cp -ip $other_file_args"
reference-variable "$CP"
alias copy='$CP'
alias del="delete"
alias copy-force='command cp -fp $other_file_args'
alias cp='command cp -i $other_file_args'
# maldito shellcheck bug: SC2032: Use own script or sh -c '..' to run this from find
# shellcheck disable=SC2032
alias rm='command rm -i $other_file_args'
alias delete='command rm -i $other_file_args'
# shellcheck disable=SC2034
{
force_echo=""
newline_tab=$'\n\t'
# TODO1: fix newline/tab support
alias disable-forced-deletions='force_echo="echo Warning: run enable-forced-deletions or issue:$newline_tab"'
alias enable-forced-deletions='force_echo=""'
}
disable-forced-deletions
#
alias delete-force='$force_echo command rm -f $other_file_args'
#
alias remove-force='delete-force'
# TODO: make sure that rellowing only applied to directories
alias remove-dir='command rm -rvi'
alias delete-dir='remove-dir'
alias remove-dir-force='$force_echo command rm -rfv'
alias delete-dir-force='remove-dir-force'
#
alias copy-readonly='copy-readonly.sh'
function copy-readonly-spec () {
local spec="$1"
local dir="$2"
if [[ ("$3" != "") || ($dir = "") || ($spec == "") ]]; then
echo "Usage: copy-readonly-spec pattern dir";
return
fi
# shellcheck disable=SC2086
for f in $($LS $spec); do copy-readonly "$f" "$dir"; done
}
# copy-readonly-to-dir(dir, file, ...): variant of copy-readonly-spec with
# directory first and files given in args 2, 3, etc.
function copy-readonly-to-dir () {
local dir="$1"
shift
for f in "$@"; do copy-readonly "$f" "$dir"; done
}
#
export NICE="nice -19"
## DUPLICATE: export TIME_CMD="/usr/bin/time"
alias fix-dir-permissions="find . -type d -exec chmod go+xs {} \;"
#-------------------------------------------------------------------------------
trace directory commands
# Support for ls (list directory contents)
#
# ls options: # --all: all files; -l long listing; -t by time; --human-readable: uses numeric suffixes like MB; --no-group: omit file permision group; --directory: no subdirectory listings.
# TODO: Add --long as alias for -l to ls source control and check-in [WTH?]! Likweise, all aliases for other common options without long names (e.g., -t).
#
LS="command ls"
core_dir_options="--all -l -t --human-readable"
dir_options="${core_dir_options} --no-group"
# shellcheck disable=SC2046,SC2086
{
if [ "$OSTYPE" = "solaris" ]; then dir_options="-alt"; fi
if [ "$BAREBONES_HOST" = "1" ]; then dir_options="-altk"; fi
function dir () {
local opts="$dir_options"
# note: see https://stackoverflow.com/questions/1853946/getting-the-last-argument-passed-to-a-shell-script
local dir="${!#}"
# hack: only shows directory contents if name ends in slash (e.g., /etc/)
# note: pattern is POSIX extended regular expression as per bash manual
local regex="^.*/$";
if [[ (! (($dir != "") || ($dir =~ $regex))) ]]; then
opts="$opts --directory";
fi
$LS ${opts} "$@" 2>&1 | $PAGER;
}
function dir-proper () { $LS ${dir_options} --directory "$@" 2>&1 | $PAGER; }
alias ls-full='$LS ${core_dir_options}'
function dir-full () { ls-full "$@" 2>&1 | $PAGER; }
## TODO: WTH with the grep (i.e., isn't there a simpler way)?
function dir-sans-backups () { $LS ${dir_options} "$@" 2>&1 | $GREP -v '~[0-9]*~' | $PAGER; }
# dir-ro/dir-rw(spec): show files that are read-only/read-write for the user
function dir-ro () { $LS ${dir_options} "$@" 2>&1 | $GREP -v '^..w' | $PAGER; }
function dir-rw () { $LS ${dir_options} "$@" 2>&1 | $GREP '^..w' | $PAGER; }
function subdirs () { $LS ${dir_options} "$@" 2>&1 | $GREP ^d | $PAGER; }
#
# subdirs-proper(): shows subdirs in column format omitting ones w/ leading dots
# note: omits cases like ./ and ./.cpan from find and then removes ./ prefix
# TODO3: have option to include dot-file subdirs like .config
quiet-unalias subdirs-proper
function subdirs-proper () { find . -maxdepth 1 -type d | $EGREP -v '^((\.)|(\.\/\..*))$' | sort | perl -pe "s@^\./@@;" | column; }
# note: -f option overrides -t: Unix sorts alphabetically by default
# via man ls:
# -f do not sort, enable -aU, disable -$LS --color
# TODO: simplify -t removal (WTH with perl regex replacement?!)
function dir_options_sans_t () { echo "$dir_options" | perl -pe 's/\-t//;'; }
function subdirs-alpha () { $LS $(dir_options_sans_t) "$@" 2>&1 | $GREP ^d | $PAGER; }
function sublinks () { $LS ${dir_options} "$@" 2>&1 | $GREP ^l | $PAGER; }
function sublinks-alpha () { $LS $(dir_options_sans_t) "$@" 2>&1 | $GREP ^l | $PAGER; }
# TODO: show non-work-related directory example
#
alias symlinks='sublinks'
# symlinks-proper: just show file name info for symbolic links, which starts at column 43
#
## BAD
## ls_filename_col=40
## if [ "$(under-macos)" = "1" ]; then ls_filename_col=42; fi
## function sublinks-proper { sublinks "$@" | cut --characters=${ls_filename_col}- | $PAGER; }
## example: "lrwxrwxrwx 1 tomohara tomohara 20 2023-06-23 16:50 mezcla -> python/Mezcla/mezcla"
## 1 2 3 4 5 6 7 8
function ls-long-tsv { ls -l --time-style=long-iso "$@" | perl -pe 's/ +/\t/g;'; }
function sublinks-proper { ls-long-tsv "$@" | $GREP ^l | alias-perl cut.perl -fields="8-" - | tr $'\t' ' ' | $PAGER; }
alias symlinks-proper=sublinks-proper
#
alias glob-links='find . -maxdepth 1 -type l | sed -e "s/.\///g"'
alias glob-subdirs='find . -mindepth 1 -maxdepth 1 -type d | sed -e "s/.\///g"'
#
alias ls-R='$LS -R >| ls-R.list; wc -l ls-R.list'
#
# TODO: create ls alias that shows file name with symbolic links (as with ls -l but without other information
# ex: ls -l | perl -pe 's/^.* \d\d:\d\d //;'
}
# link-symbolic-safe: creates symbolic link and avoids quirks with links to directories
# EX: link-symbolic-safe /tmp temp-link; link-symbolic-safe --force ~/temp temp-link; ls -l temp-link | grep /tmp => ""
# TODO3: decide on using ln-symbolic vs link-symbolic vs both
alias ln-symbolic='ln --symbolic --verbose'
alias link-symbolic=ln-symbolic
alias link-symbolic-safe='ln-symbolic --no-target-directory --no-dereference'
alias link-symbolic-regular='ln-symbolic'
alias ln-symbolic-force='ln-symbolic --force'
alias link-symbolic-force=ln-symbolic-force
#-------------------------------------------------------------------------------
trace grep commands
# check for a modern version of grep. For example,
#
# $ grep -V
# grep (GNU grep) 2.4.2
#
# Copyright 1988, 1992-1999, 2000 Free Software Foundation, Inc.
# ...
#
# In contrast, here's an old verion (e.g., under medusa):
#
# $ grep -V
# GNU grep version 2.0
# usage: grep [-[[AB] ]<num>] [-[CEFGVchilnqsvwx]] [-[ef]] <expr> [<files...>]
#
skip_dirs=""
if [[ $(grep --version) =~ Copyright.*2[0-9][0-9][0-9] ]]; then skip_dirs="-d skip"; fi
# Grep settings
# TODO: use gr and gr_ throughout for consistency
# TODO: use -P flag (i.e., --perl-regexp) w/ grep rather than egrep
# Notes:
# - MY_GREP_OPTIONS used instead of GREP_OPTIONS since grep interprets latter
# -n show line numbers
# -d skip skip directories (i.e., don't treat as files)
# -s suppress error messages (e.g., unreadable files)
# -E extended regex support (i.e., old egrep)
# - /bin/grep used to avoid alias and to allow for use with exec
# - egrep is normally used unless the pattern will never use extended regex's
## TODO: quiet-unalias grep
## TODO: add alias for resolving grep binary with fallback to "command grep"
GREP="command grep"
## NOTE: -E is --extended-regexp
EGREP="$GREP --perl-regexp"
export MY_GREP_OPTIONS="-n $skip_dirs -s"
# shellcheck disable=SC2086
{
function gr () { $GREP $MY_GREP_OPTIONS -i "$@"; }
function gr- () { $GREP $MY_GREP_OPTIONS "$@"; }
## Lorenzo review: should change this to gr-alt following TODO's
SORT_COL2="--key=2"
# grep-unique(pattern, file, ...): count occurrence of pattern in file...
function grep-unique () { $EGREP -c $MY_GREP_OPTIONS "$@" | $GREP -v ":0$" | sort -rn $SORT_COL2 -t':'; }
# grep-missing(pattern, file, ...): show files without pattern
# TODO: archive
function grep-missing () { $EGREP -c $MY_GREP_OPTIONS "$@" | $GREP ":0"; }
alias gu='grep-unique -i'
alias gu-='grep-unique'
# gu-all: run gu over all files in current dir
# TODO: archive
function gu-all () { grep-unique "$@" ./* | $PAGER; }
#
function gu- () { $GREP -c $MY_GREP_OPTIONS "$@" | $GREP -v ":0"; }
## Lorenzo review: should change this to gu-alt following TODO's
#
# grepl(pattern, [other_grep_args]): invokes grep over PATTERN and OTHER_GREP_ARGS and then pipes into less for PATTERN
# NOTE: actually uses egrep
# TODO: use more general way to ensure pattern given last while readily extractable for less -p usage
function grep-to-less () {
# TODO: fix warning about possible discrepency between grep regex and less, such as when ^ used (e.g., with multiple files in grep output)
if [[ ($1 =~ ^[^]) && ($# -gt 2) ]]; then
echo "Error: ^ will be intrepretted differently by less (e.g., due to multiple files)" 1>&2
else
$EGREP $MY_GREP_OPTIONS "$@" | $PAGER_NOEXIT -p"$1";
fi
}
alias grepl-='grep-to-less'
function grepl () { pattern="$1"; shift; grep-to-less "$pattern" -i "$@"; }
}
# gr-c: grep through c/c++ source and headers files
# note: --no-messages suppresses warnings about missing files
function gr-c () { gr --no-messages "$@" ./*.c ./*.cpp ./*.cxx ./*.h; }
# TODO: create function for creating gr-xyz aliases
# TODO: -or- create gr-xyz template
## function gr-xyz () { gr- "$@" *.xyz; }
# show-line-context(file, line-num): show 5 lines before LINE-NUM in FILE
# TODO: archive
function show-line-context() { cat -n "$1" | $GREP -B5 "^\W+$2\W"; }
# Helper function for grep-based aliases pipe into less
function gr-less () { gr "$@" | $PAGER; }
# Other grep-related stuff
#
# EX: echo $'L1: one\nL2: \xC3\xBE \nL3: three' | gr-nonascii => "2: L2: þ"
alias grep-nonascii='alias-perl perlgrep.perl "[\x80-\xFF]"'
alias gr-nonascii='perlgrep.perl -n "[\x80-\xFF]"'
# Searching for files
# TODO:
# - specify find options in an environment variable
# - rework in terms of Perl regex? (or use -iregex in place of -iname)
#
# shellcheck disable=SC2086
{ # start shellcheck block
function findspec () { if [ "$2" = "" ]; then echo "Usage: findspec dir glob-pattern find-option ... "; else command find $1 -iname \*$2\* $3 $4 $5 $6 $7 $8 $9 2>&1 | $GREP -v '^find: '; fi; }
# findspec[-all](dir, pattern, option): find files in directory tried, optionally following links (-all)
function findspec-all () { command find $1 -follow -iname \*$2\* $3 $4 $5 $6 $7 $8 $9 -print 2>&1 | $GREP -v '^find: '; }
function fs () { findspec . "$@" | $EGREP -iv '(/(backup|build)/)'; }
function fs-ls () { fs "$@" -exec ls -l {} \; ; }
alias fs-='findspec-all .'
## Lorenzo review: should change this to fs-alt following TODO's
function fs-ext () { find . -iname \*."$1" | $EGREP -iv '(/(backup|build)/)'; }
# TODO: extend fs-ext to allow for basename pattern (e.g., fs-ext java ImportXML)
function fs-ls- () { fs- "$@" -exec ls -l {} \; ; }
## Lorenzo review: should change this to fs-ls-alt following TODO's
#
findgrep_opts="-in"
#
# NOTE: findgrep macros use $findgrep_opts dynamically (eg, user can change $findgrep_opts)
function findgrep-verbose () { find "$1" -iname \*"$2"\* -print -exec $GREP $findgrep_opts "$3" $4 $5 $6 $7 $8 $9 \{\} \;; }
# findgrep(dir, filename_pattern, line_pattern): $GREP through files in DIR matching FILENAME_PATTERN for LINE_PATTERN
function findgrep () { find $1 -iname \*"$2"\* -exec $GREP $findgrep_opts "$3" $4 $5 $6 $7 $8 $9 \{\} /dev/null \;; }
# TODO: archive
function findgrep- () { find $1 -iname $2 -print -exec $GREP $findgrep_opts "$3" $4 $5 $6 $7 $8 $9 \{\} \;; }
## Lorenzo review: should change this to findgrep-alt following TODO's
function findgrep-ext () { local dir="$1"; local ext="$2"; shift; shift; find "$dir" -iname "*.$ext" -exec $GREP $findgrep_opts "$@" \{\} /dev/null \;; }
# fgr(filename_pattern, line_pattern): $GREP through files matching FILENAME_PATTERN for LINE_PATTERN
function fgr () { findgrep . "$@" | $EGREP -v '((/backup)|(/build))'; }
function fgr-ext () { findgrep-ext . "$@" | $EGREP -v '(/(backup)|(build)/)'; }
alias fgr-py='fgr-ext py'
alias fgr-java='fgr-ext java'
#
# prepare-find-files-here([--out-dir out_dir_spec]): produces listing(s) of files in current directory
# tree, in support of find-files-here; this contains full ls entry (as with -l).
# (The subdirectory listings produced by 'ls -alR' are preceded by blank lines,
# which is required for find-files-here as explained below.)
# Notes: Also puts listing proper in ls-aR.list (i.e., just list of files).
# TODO: create external script and have alias call the script
# Ignores SC2068: Double quote array expansions