aboutsummaryrefslogtreecommitdiffhomepage
path: root/init/fish_function.fish
blob: 9aa425c8f70b24608358e9c5d85cfc2d6ac33dfd (plain)
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
#
# This file defines various functions for fish
#


function _contains_help -d "Helper function for contains"
	echo "SYNOPSIS"
	echo \tcontains \[OPTION] KEY [VALUES...]
	echo
	echo DESCRIPTION
	echo \t-h, --help
	echo \t\tdisplay help and exit
	echo \tTest if the set VALUES contains the string KEY.
	echo \tReturn 0 if yes, 1 otherwise.
end

function contains -d "Test if a key is contained in a set of values"
	while count $argv >/dev/null
		switch $argv[1]
			case '-h' '--h' '--he' '--hel' '--help'
				_contains_help
				return

			case '--'
				# End the loop, the next argument is the key
				set -e argv[1]
				break
			
			case '-*'
				echo Unknown option $argv[$i]
				_contains_help
				return 1

			case '*'
				# End the loop, we found the key
				break				

		end
		set -e argv[1]
	end

	if count $argv >/dev/null
	else
		echo "contains: Key not specified"
		return 1
	end

	set -- key $argv[1]
	set -e argv[1]	

	#
	# Loop through values
	#

	printf "%s\n" $argv|grep -Fx -- $key >/dev/null
	return $status
end

#
# help should use 'open' to find a suitable browser, but only
# if there is a mime database _and_ DISPLAY is set, since the
# browser will most likely be graphical. Since most systems which
# have a mime databe also have the htmlview program, this is mostly a
# theoretical problem.
#

function help -d "Show help for the fish shell"

	# Declare variables to set correct scope

	set fish_browser
	set fish_browser_bg

	#
	# Find a suitable browser for viewing the help pages. This is needed
	# by the help function defined below.
	#

	set graphical_browsers htmlview x-www-browser firefox galeon mozilla konqueror epiphany opera netscape
	set text_browsers htmlview www-browser links elinks lynx w3m

	if test $BROWSER

		# User has manualy set a preferred browser, so we respect that
		set fish_browser $BROWSER

		# If browser is known to be graphical, put into background
		if contains -- $BROWSER $graphical_browsers
			set fish_browser_bg 1
		end

	else

		# Check for a text-based browser.
		for i in $text_browsers
			if which $i 2>/dev/null >/dev/null
				set fish_browser $i
				break
			end
		end

		# If we are in a graphical environment, we check if there is a
		# graphical browser to use instead.
		if test (echo $DISPLAY)
			for i in $graphical_browsers
				if which $i 2>/dev/null >/dev/null
					set fish_browser $i
					set fish_browser_bg 1
					break
				end
			end
		end
	end

	if test -z $fish_browser
		printf "help: Could not find a web browser.\n"
		printf "Please set the variable $BROWSER to a suitable browser and try again\n\n"
		return 1
	end

	set fish_help_item $argv[1]
	set fish_help_page ""

	if test $fish_help_item = .
		set fish_help_page "builtins.html\#source"
	end

	if test $fish_help_item = difference
		set fish_help_page difference.html
	end

	if test $fish_help_item = globbing
		set fish_help_page "index.html\#expand"
	end

	if contains -- $fish_help_item (builtin -n)
		set fish_help_page "builtins.html\#"$fish_help_item
	end
	
	if contains -- $fish_help_item count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize
		set fish_help_page "commands.html\#"$fish_help_item
	end
	
	set idx_subj syntax completion editor job-control todo bugs history
	set idx_subj $idx_subj killring help color prompt title expand variables
	set idx_subj $idx_subj builtin-overview changes

	if contains -- $fish_help_item $idx_subj
		set fish_help_page "index.html\#"$fish_help_item
	end

	if not test $fish_help_page
		if which $fish_help_item >/dev/null ^/dev/null
			man $fish_help_item
			return
		end
		set fish_help_page "index.html"
	end

	if test $fish_browser_bg
		eval $fish_browser file://$__fish_help_dir/$fish_help_page \&
	else
		eval $fish_browser file://$__fish_help_dir/$fish_help_page
	end

end

#
# Make ls use colors if we are on a system that supports this
#
if ls --help 1>/dev/null 2>/dev/null
	function ls -d "List contents of directory"
		command ls --color=auto --indicator-style=classify $argv
	end
end

#
# These are very common and useful
#
function ll -d "List contents of directory using long format"
	ls -lh $argv
end

function la -d "List contents of directory using long format, showing hidden files"
	ls -lha $argv
end

#
# This allows us to use 'open FILENAME' to open a given file in the default
# application for the file.
#

function open -d "Open file in default application"
	mimedb -l -- $argv
end

#
# Print the current working directory. If it is too long, it will be
# ellipsised. This function is used by the default prompt command.
#

function prompt_pwd -d "Print the current working directory, ellipsise it if it is longer than 1/4 of the terminal width"
	set wd (pwd)
	set len (echo $wd|wc -c)
	set max_width (echo $COLUMNS/4|bc)
	if test $len -gt $max_width
		#Write ellipsis character if known to be using UTF
		#else use $
		set -l ellipsis "$" #default
		if count $LANG >/dev/null
			if test (expr match $LANG ".*UTF") -gt 0
				set ellipsis \u2026
			end
		end
		printf %s%s $ellipsis (echo $wd|cut -c (echo $len-$max_width-1|bc)-)
	else
		echo $wd
	end
end

#
# Make pwd print out the home directory as a tilde.
#

function pwd -d "Print working directory"
	set out (command pwd $argv)
	if echo $out| grep \^$HOME >/dev/null
		printf \~
		echo $out |cut -b (echo $HOME|wc -c)-
	else
		printf "%s\n" $out
	end
end

#
# This is a neat function, stolen from zsh. It allows you to edit the
# value of a variable interactively.
#

function vared -d "Edit variable value"
	if test (count $argv) = 1
		switch $argv

			case '-h' '--h' '--he' '--hel' '--help'
				printf "Synopsis\n\t%svared%s VARIABLE\n\n" (set_color $fish_color_command) (set_color normal)
				printf "\tInteractively edit the value of an environment variable\n\n"

			case '-*'
				printf "vared: Unknown option %s\n" $argv

			case '*'
				if test (count $$argv ) -lt 2
					set init ''
					if test $$argv
						set init -- $$argv
					end
					set prompt 'set_color green; echo '$argv'; set_color normal; echo "> "'
					read -p $prompt -c $init tmp

					# If variable already exists, do not add any
					# switches, so we don't change export rules. But
					# if it does not exist, we make the variable
					# global, so that it will not die when this
					# function dies

					if test $$argv
						set -- $argv $tmp
					else
						set -g -- $argv $tmp
					end

				else

					printf "vared: %s is an array variable. Use " $argv
					set_color $FISH_COLOR_COMMAND
					printf vared
					set_color $FISH_COLOR_NORMAL
					printf " %s[n] to edit the n:th element of %s\n" $argv $argv

				end
		end
	else
		printf "vared: Expected exactly one argument, got %s.\n\nSynopsis:\n\t" (count $argv)
		set_color $FISH_COLOR_COMMAND
		printf vared
		set_color $FISH_COLOR_NORMAL
		printf " VARIABLE\n"
	end
end

#
# This function is bound to Alt-L, it is used to list the contents of
# the directory under the cursor
#

function __fish_list_current_token -d "List contents of token under the cursor if it is a directory, otherwise list the contents of the current directory"
	set val (eval echo (commandline -t))
	if test -d $val
		ls $val
	else
		set dir (dirname $val)
		if test $dir != . -a -d $dir
			ls $dir
		else
			ls
		end
	end
end


function pushd -d "Push directory to stack"
	# Comment to avoid set completions
	set -g dirstack (command pwd) $dirstack
	cd $argv[1]
end


function popd -d "Pop dir from stack"
	if test $dirstack[1]
		cd $dirstack[1]
	else
		echo Directory stack is empty...
		return 1
	end

	set -e dirstack[1]

end


function dirs -d "Print directory stack"
	echo -n (command pwd)"  "
	for i in $dirstack
		echo -n $i"  "
	end
	echo
end


#
# The following functions add support for a directory history
#

function cd -d "Change directory"

	# Skip history in subshells
	if status --is-command-substitution
		builtin cd $argv
		return $status
	end

	# Avoid set completions
	set -- previous (command pwd)

	if test $argv[1] = - ^/dev/null
		if test $__fish_cd_direction = next ^/dev/null
			nextd
		else
			prevd
		end
		return $status
	end
				
	builtin cd $argv[1]

	if test $status = 0 -a (command pwd) != $previous
		set -g dirprev $dirprev $previous
		set -e dirnext
		set -g __fish_cd_direction prev
	end

	return $status
end


function __fish_move_last -d "Move the last element of a directory history from src to dest"
	set src $argv[1]
	set dest $argv[2]

	set size_src (count $$src)

	if test $size_src = 0
		# Cannot make this step
		echo "Hit end of history..."
		return 1
	end

	# Append current dir to the end of the destination
	set -g (echo $dest) $$dest (command pwd)

	set ssrc $$src
		
	# Change dir to the last entry in the source dir-hist
	builtin cd $ssrc[$size_src]

	# Keep all but the last from the source dir-hist 
	set -e (echo $src)[$size_src]

	# All ok, return success
	return 0
end	


function prevd -d "Move back in the directory history"
	# Parse arguments
	set show_hist 0 
	set times 1
	for i in (seq (count $argv))
		switch $argv[$i]
			case '-l'
				set show_hist 1
				continue
			case '-*'
				echo Uknown option $argv[$i]
				return 1
			case '*'
				if test $argv[$i] -ge 0 ^/dev/null
					set times $argv[$i]
				else
					echo "The number of positions to skip must be a non-negative integer"
					return 1
				end
				continue
		end
	end

	# Traverse history
	set code 1
	for i in (seq $times)
		# Try one step backward
		if __fish_move_last dirprev dirnext;
			# We consider it a success if we were able to do at least 1 step
			# (low expectations are the key to happiness ;)
			set code 0
		else
			break
		end
	end

	# Show history if needed
	if test $show_hist = 1
		dirh
	end

	# Set direction for 'cd -'
	if test $code = 0 ^/dev/null
		set -g __fish_cd_direction next
	end

	# All done
	return $code
end 


function nextd -d "Move forward in the directory history"
	# Parse arguments
	set show_hist 0 
	set times 1
	for i in (seq (count $argv))
		switch $argv[$i]
			case '-l'
				set show_hist 1
				continue
			case '-*'
				echo Uknown option $argv[$i]
				return 1
			case '*'
				if test $argv[$i] -ge 0 ^/dev/null
					set times $argv[$i]
				else
					echo "The number of positions to skip must be a non-negative integer"
					return 1
				end
				continue
		end
	end

	# Traverse history
	set code 1
	for i in (seq $times)
		# Try one step backward
		if __fish_move_last dirnext dirprev;
			# We consider it a success if we were able to do at least 1 step
			# (low expectations are the key to happiness ;)
			set code 0
		else
			break
		end
	end

	# Show history if needed
	if test $show_hist = 1
		dirh
	end

	# Set direction for 'cd -'
	if test $code = 0 ^/dev/null
		set -g __fish_cd_direction prev
	end

	# All done
	return $code
end 


function dirh -d "Print the current directory history (the back- and fwd- lists)" 
	# Avoid set comment
	set current (command pwd)
	set -- separator "  "
	set -- line_len (echo (count $dirprev) + (echo $dirprev $current $dirnext | wc -m) | bc)
	if test $line_len -gt $COLUMNS
		# Print one entry per line if history is long
		set separator "\n"
	end

	for i in $dirprev
		echo -n -e $i$separator
	end

	set_color $fish_color_history_current
	echo -n -e $current$separator
	set_color normal
	
	for i in (seq (echo (count $dirnext)) -1 1)
		echo -n -e $dirnext[$i]$separator
	end

	echo
end

function __bold -d "Print argument in bold"
	set_color --bold
	printf "%s" $argv[1]
	set_color normal
end

function __type_help -d "Help for the type shellscript function"

echo \ttype type - Indicate how a name would be interpreted if used as a command name
echo (__bold Synopsis)
echo \t(set_color $fish_color_command)type(set_color normal) [OPTIONS] name [name ...]
echo
echo (__bold Description)
echo
echo \tWith no options, indicate how each name would be interpreted if used as a command name.  
echo
echo \t\* (__bold -h) or (__bold --help) print this message
echo \t\* (__bold -a) or (__bold --all) print all of possible definitions of the specified names
echo \t\* (__bold -f) or (__bold --no-functions) supresses function and builtin lookup
echo \t\* (__bold -t) or (__bold --type) print a string which is one of alias, keyword, function, builtin, or file if name is an alias, shell reserved word, function, builtin, or disk file, respectively
echo \t\* (__bold -p) or (__bold --path) either return the name of the disk file that would be executed if name were specified as a command name, or nothing if ‘‘type  -t  name’’ would  not  return  file
echo \t\* (__bold -P) or (__bold --force-path) either return the name of the disk file that would be executed if name were specified as a command name, or nothing no file with the spacified name could be found in the PATH
echo
echo (__bold Example)
echo
echo \t\'(set_color $fish_color_command)type(set_color normal) fg\' outputs the string \'fg is a shell builtin\'.
echo

end

function type -d "Print the type of a command"

	set status 1
	set mode normal
	set selection all

	for i in $argv
		switch $i
			case -t --t --ty --typ --type
				set mode type
			
			case -p --p --pa --pat --path
				set mode path
			
			case -P --f --fo --for --forc --force --force- --force-p --force-pa --force-pat --force-path 
				set mode path
				set selection files
			
			case -a --a --al --all
				set selection multi

			case -f --n --no --no- --no-f --no-fu --no-fun --no-func --no-funct --no-functi --no-functio --no-function --no-functions
				set selection files

			case -h --h --he --hel --help
				 __type_help

			case --
				 break

			case '-*'
				 echo Unknown option $i
				 return 1
		end
	end

	for i in $argv
		
		switch $i
			case '-*'
				 continue
		end

		# Found will be set to 1 if a match is found
		set found 0

		if test $selection != files

			if contains -- $i (functions -n)
				set status 0
				set found 1
				switch $mode
					case normal
						echo $i is a function with definition
						functions $i

					case type
						echo function

					case path
						 echo

				end
				if test $selection != multi
					continue
				end
			end

			if contains -- $i (builtin -n)
				set status 0
				set found 1
				switch $mode
					case normal
						echo $i is a builtin

					case type
						echo builtin

					case path
						echo
				end
				if test $selection != multi
					continue
				end
			end

		end

		if which $i ^/dev/null >/dev/null
			set status 0
			set found 1
			switch $mode
				case normal
					echo $i is (which $i)

					case type
						echo file

					case path
						which $i
			end
			if test $selection != multi
				continue
			end
		end

		if test $found = 0
			echo type: $i: not found
		end

	end

	return $status
end


if status --is-interactive

function prevd-or-backward-word --key-binding 
	if test -z (commandline)
		prevd
	else
		commandline -f backward-word
	end
end

function nextd-or-forward-word --key-binding 
	if test -z (commandline)
		nextd
	else
		commandline -f forward-word
	end
end

#
# This function deletes a character from the commandline if it is
# non-empty, and exits the shell otherwise. Implementing this
# functionality has been a longstanding request from various
# fish-users.
#

function delete-or-exit --key-binding 
	if test (commandline)
		commandline -f delete-char
	else
		exit
	end
end

end