Skip to content

Instantly share code, notes, and snippets.

@emad-elsaid
Created October 14, 2019 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emad-elsaid/9964d0cd8eff9b1999858eeb11a53e01 to your computer and use it in GitHub Desktop.
Save emad-elsaid/9964d0cd8eff9b1999858eeb11a53e01 to your computer and use it in GitHub Desktop.

the bash_profile snippet will let you run the first file when you press tab when you have empty command , you need to put the cmd file in your path and make it executable with chmod +x cmd

# functions
cmd_complete () {
COMPREPLY+=("`cmd print`")
}
complete -F cmd_complete -E
#!/usr/bin/env ruby
# How to use that script
# =======================
#
# I write several small scripts to aid me in my workflow, I usually keep them in
# one directory added to my PATH but that means to execute one of them I need to
# recall the name of every script, but in reality I forget that That I even
# wrote it and sometimes I rewrite the same script many times because of this.
#
# So what I learned here is that these scripts needs a long meaningful name, and
# some interface to search through them an interface that's flexible enough like
# Emacs helm package, a fuzzy finder that search through a long list of scripts
# and when I find the script I need I'll execute it.
#
# I found that FZF is a good interface and I wrote that script around it, this
# script below will open FZF passing all executable scripts found in "Sources
# Directories"+PATH directories (coming below what are they), when you choose a
# script it will execute it. another feature I added is a documentation panel,
# that shows the file if it's a text file or the man page if binary so when you
# cycle through the list you see the documentation of it.
#
# Source Directories: directories that has executable scripts, that script keeps
# a list of them in ~/.cmd/sources you can add your directories with `cmd
# add-sources /path/dir1...` or simply edit the file with your favorite text
# editor
#
# If you names that script 'cmd' and put it in your PATH, adding the following
# to your ~/.bashrc will let you press TAB in commandline while it's empty to
# lunch that script and print the command path at your shell, it's useful for
# scripts that needs arguments
#
# cmd_complete () {
# COMPREPLY+=("`cmd print`")
# }
# complete -F cmd_complete -E
require 'fileutils'
require 'mkmf'
command = ARGV.first
separator = "\t"
conf_dir = File.expand_path(File.join('~/.cmd'))
history = File.join(conf_dir, 'history')
sources = File.join(conf_dir, 'sources')
fzf = "#{__FILE__} list | fzf --tiebreak=begin --ansi --preview='#{__FILE__} preview {2}' --reverse --preview-window=right:50% --nth=1 --with-nth=1 --delimiter='#{separator}' --history=#{history} --prompt=' ➜ '"
Dir.mkdir(conf_dir) unless File.exist?(conf_dir)
FileUtils.touch(sources) unless File.exist?(sources)
case command
when nil
line = `#{fzf}`
exit if line.empty?
script = line.split(separator)[1].gsub(' ', '\ ')
system(script)
when 'print'
line = `#{fzf}`
exit if line.empty?
script = line.split(separator)[1].gsub(' ', '\ ').strip
print script
when 'list'
sources_dirs = File.read(sources).lines.map(&:strip).reject(&:empty?)
path_dirs = ENV['PATH'].split(':').reject(&:empty?)
dirs = (sources_dirs + path_dirs).uniq
files = Dir.glob("{#{dirs.join(',')}}/**/*").uniq
files.select! do |f|
File.file?(f) && File.executable?(f)
end
files.map! do |f|
name = File.basename(f).capitalize
"#{name}#{separator}#{f}"
end
puts files
when 'preview'
path = ARGV[1]
type = `file "#{path}"`
if type.include?('text')
if find_executable0('bat') != nil
puts `script -qfc "bat --paging=never '#{path}'" /dev/null`
else
puts File.read(path)
end
else
puts `man "#{path}"`
end
when 'list-sources'
puts File.read(sources)
when 'add-sources'
new_sources = ARGV[1..-1]
current_sources = File.read(sources).lines.map(&:strip).reject(&:empty?)
all_sources = current_sources + new_sources
File.write(sources, all_sources.uniq.join("\n"))
puts 'sources added..'
else
puts 'Command is not recognized.'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment