Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some macOS completions #3524

Merged
merged 8 commits into from Nov 6, 2016
Merged

Conversation

elnappo
Copy link
Contributor

@elnappo elnappo commented Nov 4, 2016

Description

Added some macOS completions for mdutil, mdfind, mdls, nvram and tmutil.

mdutil

Could be a little bit nicer but I have no idea how to convert

/:
	Indexing enabled.
/.MobileBackups:
	No index.

to

/<TAB>Indexing enabled.
/.MobileBackups<TAB>No index.

I tried command mdutil -a -s | string replace '\n\t' '\t'

Usage: mdutil -pEsa -i (on|off) -d volume ...
       mdutil -t {volume-path | deviceid} fileid
	Utility to manage Spotlight indexes.
	-p             Publish metadata.
	-i (on|off)    Turn indexing on or off.
	-d             Disable Spotlight activity for volume (re-enable using -i on).
	-E             Erase and rebuild index.
	-s             Print indexing status.
	-t             Resolve files from file id with an optional volume path or device id.
	-a             Apply command to all volumes.
	-V vol         Apply command to all stores on the specified volume.
	-v             Display verbose information.
NOTE: Run as owner for network homes, otherwise run as root.
mdutil(1)                 BSD General Commands Manual                mdutil(1)

NAME
     mdutil -- manage the metadata stores used by Spotlight

SYNOPSIS
     mdutil [-pEsav] [-i on | off] mountPoint ...

DESCRIPTION
     The mdutil command is useful for managing the metadata stores for mounted volumes.

     The following options are available:

     -p  Spotlight caches indexes of some network devices locally.  This option requests that a local caches be flushed to the appropriate network device.

     -E  This flag will cause each local store for the volumes indicated to be erased.  The stores will be rebuilt if appropriate.

     -i on | off
         Sets the indexing status for the provided volumes to on or off.  Note that indexing may be delayed due to low disk space or other conditions.

     -d  Disables Spotlight searches on the provided volume.

     -s  Display the indexing status of the listed volumes.

     -a  Apply command to all volumes.

     -v  Print verbose information when available.

SEE ALSO
     mdfind(1), mds(8), mdimport(1)

Mac OS X                       September 1, 2005                      Mac OS X

mdfind

I'm not aware of any command which returns common attributes.

Usage: mdfind [-live] [-count] [-onlyin directory] [-name fileName | -s smartFolderName | query]
list the files matching the query
query can be an expression or a sequence of words

	-attr <attr>      Fetches the value of the specified attribute
	-count            Query only reports matching items count
	-onlyin <dir>     Search only within given directory
	-live             Query should stay active
	-name <name>      Search on file name only
	-reprint          Reprint results on live update
	-s <name>         Show contents of smart folder <name>
	-0                Use NUL (``\0'') as a path separator, for use with xargs -0.

example:  mdfind image
example:  mdfind -onlyin ~ image
example:  mdfind -name stdlib.h
example:  mdfind "kMDItemAuthor == '*MyFavoriteAuthor*'"
example:  mdfind -live MyFavoriteAuthor
mdfind(1)                 BSD General Commands Manual                mdfind(1)

NAME
     mdfind -- finds files matching a given query

SYNOPSIS
     mdfind [-live] [-count] [-onlyin directory] [-name fileName] query

DESCRIPTION
     The mdfind command consults the central metadata store and returns a list of files that match the given metadata query. The query can be a string or a query expression.

     The following options are available:

     -0          Prints an ASCII NUL character after each result path.  This is useful when used in conjunction with xargs -0.

     -live       Causes the mdfind command to provide live-updates to the number of files matching the query.  When an update causes the query results to change the number of matches is updated.  The find can be
                 cancelled by typing ctrl-C.

     -count      Causes the mdfind command to output the total number of matches, instead of the path to the matching items.

     -onlyin dir
                 Limit the scope of the search to the directory specified.

     -name fileName
                 Searches for matching file names only.

     -literal    Force the provided query string to be taken as a literal query string, without interpretation.

     -interpret  Force the provided query string to be interpreted as if the user had typed the string into the Spotlight menu.  For example, the string "search" would produce the following query string:
                       (* = search* cdw || kMDItemTextContent = search* cdw)

EXAMPLES
     The following examples are shown as given to the shell.

     This returns all files with any metadata attribute value matching the string "image":

           mdfind image

     This returns all files that contain "MyFavoriteAuthor" in the kMDItemAuthor metadata attribute:

           mdfind "kMDItemAuthors == '*MyFavoriteAuthor*'"

     This returns all files with any metadata attribute value matching the string "skateboard".  The find continues to run after gathering the initial results, providing a count of the number of files that match
     the query.

           mdfind -live skateboard

     To get a list of the available attributes for use in constructing queries, see mdimport(1), particularly the -X switch.

SEE ALSO
     mdimport(1), mdls(1), mdutil(1), xargs(1)

Mac OS X                         June 10, 2004                        Mac OS X

mdls

usage: mdls [-name attr] [-raw [-nullMarker markerString]] [-plist file] path
list the values of one or all the attributes of the specified file
  -raw:         don't print attribute names before values
  -nullMarker:  substitute this string for null attributes in raw mode
  -plist:       output attributes in XML format to file. Use - to write to stdout
                option -plist is incompatible with options -raw, -nullMarker, and -name
example:  mdls  ~/Pictures/Birthday.jpg
example:  mdls  -name Keyword ~/Pictures/Birthday.jpg
MDLS(1)                   BSD General Commands Manual                  MDLS(1)

NAME
     mdls -- lists the metadata attributes for the specified file

SYNOPSIS
     mdls [-name attributeName] [-raw [-nullMarker markerString]] file ...

DESCRIPTION
     The mdls command prints the values of all the metadata attributes associated with the files provided as an argument.

     The following options are available:

     -name        Print only the matching metadata attribute value.  Can be used multiple times.

     -raw         Print raw attribute data in the order that was requested.  Fields will be separated with a ASCII NUL character, suitable for piping to xargs(1) -0.

     -nullMarker  Sets a marker string to be used when a requested attribute is null.  Only used in -raw mode.  Default is "(null)".

SEE ALSO
     mdfind(1), mdutil(1) xargs(1)

Mac OS X                         June 3, 2004                         Mac OS X

nvram

nvram [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...
	-x         use XML format for printing or reading variables
	           (must appear before -p or -f)
	-p         print all firmware variables
	-f         set firmware variables from a text file
	-d         delete the named variable
	-c         delete all variables
	name=value set named variable
	name       print variable
Note that arguments and options are executed in order
nvram(8)                                                                                                                                                                                                      nvram(8)

NAME
       nvram - manipulate firmware NVRAM variables

SYNOPSIS
       nvram [ -p ] [ -f filename ] [ -d name ] [ -c ] [ name [= value ]] ...

DESCRIPTION
       The  nvram  command  allows  manipulation  of  firmware  NVRAM  variables.  It can be used to get or set a variable.  It can also be used to print all of the variables or set a list of variables from a file.
       Changes to NVRAM variables are only saved by clean restart or shutdown.

       In principle, name can be any string.  In practice, not all strings will be accepted.  New World machines can create new variables as desired.  Some variables require administrator privilege to get or set.

       The given value must match the data type required for name.  Binary data can be set using the %xx notation, where xx is the hex value of the byte.  The type for new variables is always binary data.

OPTIONS
       -d name
              Deletes the named firmware variable.

       -f filename
              Set firmware variables from a text file.  The file must be a list of "name value" statements.  The first space on each line is taken to be the separator between "name" and "value".  If the last  char-
              acter of a line is \, the value extends to the next line.

       -x     Use XML format for reading and writing variables.  This option must be used before the -p or -f options, since arguments are processed in order.

       -c     Delete all of the firmware variables.

       -p     Print all of the firmware variables.

EXAMPLES
              example% nvram boot-args="-s rd=*hd:10"

       Set the boot-args variable to "-s rd=*hd:10".  This would specify single user mode with the root device in hard drive partition 10.

              example% nvram my-variable="String One%00String Two%00%00"

       Create a new variable, my-variable, containing a list of two C-strings that is terminated by a NUL.

              example% nvram -d my-variable

       Deletes the variable named my-variable.

                                                                                                   October 28, 2003                                                                                           nvram(8)

tmutil

Manpage

Usage: tmutil version
Usage: tmutil enable
Usage: tmutil disable
Usage: tmutil startbackup [-a | --auto] [-b | --block] [-r | --rotation] [-d | --destination dest_id]
Usage: tmutil stopbackup
Usage: tmutil enablelocal
Usage: tmutil disablelocal
Usage: tmutil snapshot
Usage: tmutil delete snapshot_path ...
Usage: tmutil restore [-v] src ... dst
Usage: tmutil compare [-@acdefghlmnstuEX] [-D depth] [-I name]
       tmutil compare [-@acdefghlmnstuEX] [-D depth] [-I name] snapshot_path
       tmutil compare [-@acdefghlmnstuEUX] [-D depth] [-I name] path1 path2
Usage: tmutil setdestination [-a]  mount_point
       tmutil setdestination [-ap] afp://user[:pass]@host/share
Usage: tmutil removedestination destination_id
Usage: tmutil destinationinfo [-X]
Usage: tmutil addexclusion [-p|-v] item ...
Usage: tmutil removeexclusion [-p|-v] item ...
Usage: tmutil isexcluded item ...
Usage: tmutil inheritbackup machine_directory
       tmutil inheritbackup sparse_bundle
Usage: tmutil associatedisk [-a] mount_point volume_backup_directory
Usage: tmutil latestbackup
Usage: tmutil listbackups
Usage: tmutil machinedirectory
Usage: tmutil calculatedrift machine_directory
Usage: tmutil uniquesize path ...
Usage: tmutil verifychecksums path ...

Fixes issue #

TODOs:

  • Changes to fish usage are reflected in user documenation/manpages.
  • Tests have been added for regressions fixed

# completion for nvram (macOS)

function __fish_nvram_variables
command nvram -p
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, not really necessary to define a function here -- you could run nvram -p directly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in two places, so I'm actually okay with this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, it seems a little bit unnecessary to me still, but I've removed the change request.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I removed parts of the output but then discovered the "tab trick" which now displays the actual values of the variables.

@floam
Copy link
Member

floam commented Nov 4, 2016

Happy to see these OS X utilities start to get some love.

@floam
Copy link
Member

floam commented Nov 4, 2016

mdfind has a few more flags, like -interpret. I don't see them defined here, although the manpage completion generator does fill them in.

And what would be amazing (and not easy at all, really hard) would be help constructing the queries, as they are undiscoverable: mdfind "kMDItemContentType == public.unix-executable" .
Seriously, that'd be really crazy hard to complete properly, but cool.

@faho
Copy link
Member

faho commented Nov 4, 2016

Could be a little bit nicer but I have no idea how to convert

    Indexing enabled.
/.MobileBackups:
    No index.

to

/<TAB>Indexing enabled.
/.MobileBackups<TAB>No index.

I tried command mdutil -a -s | string replace '\n\t' '\t'

I can't think of a simple solution either - alternating lines isn't something unixy tools are great at. Of course awk could help here but that's a swiss-army chainsword and AFAIK the macOS version is kinda crappy.

So how about something like this:

command mdutil -a -s | while read -l line
    if string match -q \t"*" -- $line
        printf "%s\n" $line
    else
        # Use printf to not output a newline so indented lines are joined
        # to non-indented ones
        printf "%s" (string replace -r ':$' '' -- $line)
    end
end

@faho faho added this to the next-2.x milestone Nov 4, 2016
@elnappo
Copy link
Contributor Author

elnappo commented Nov 5, 2016

@floam Thanks! I missed that. Your'e right, but I not sure if anyone is using this anyway.
@faho Thank you! :)

@elnappo
Copy link
Contributor Author

elnappo commented Nov 5, 2016

I've added two more completions for mdimport and mddiagnose.

mdimport

Usage: mdimport [OPTION] path
    -d debugLevel Integer between 1-4
    -g plugin     Import files using the listed plugin, rather than the system installed plugins.
    -p            Print out performance information gathered during the run
    -A            Print out the list of all of the attributes and exit
    -X            Print out the schema file and exit
    -L            Print out the List of plugins that we are going to use and exit
    -r            Ask the server to reimport files for UTIs claimed by the listed plugin.
    -n            Don't send the imported attributes to the data store.
    -o path       Write the imported attributes to a file, instead of sending them to the server.
mdimport(1)               BSD General Commands Manual              mdimport(1)

NAME
     mdimport, mdimport32 -- import file hierarchies into the metadata datastore.

SYNOPSIS
     mdimport [-VXLArgn] [-d level | category] [-w delay] file | directory
     mdimport32 [-VXLArgn] [-d level | category] [-w delay] file | directory

DESCRIPTION
     mdimport is used to test Spotlight plug-ins, list the installed plug-ins and schema, and re-index files handled by a plug-in when a new plug-in is installed.

     mdimport32 is used in exactly the same way, but for 32 bit plugins.

     The following options are available:

     -g plugin   Load the plugin at the provided path, ignoring system installed plugins.  Useful for testing plugins that have not yet been installed.

     -V          Print timing information for this run of mdimport.

     -A          Print out the list of all of the attributes and their localizations in the current language and exit.

     -X          Print the schema file and exit

     -r          Ask the server to reimport files for UTIs claimed by the listed plugin.  For example, the following would cause all of the chat files on the system to be reimported:

                       mdimport -r /System/Library/Spotlight/Chat.mdimporter

     -p          Print out performance information gathered during the run.

     -L          Print the list of installed importers and exit.

     -d level    Print debugging information.  Level can be 1-4.

     -n          Don't actually set the attributes on the file.  Useful for debugging.

     -w msecs    Wait for the specified interval between scanning files.

NOTES
     The -f switch is obsolete in Leopard and beyond.

SEE ALSO
     mdfind(1), mdutil(1), mdls(1)

Mac OS X                         Oct 27, 2004                         Mac OS X

mddiagnose

Usage: mddiagnose [OPTIONS]
    Must be run as 'root' unless option -p is used.
    -h  Display this help
    -d  Ignore unknown options
    -e <path>   Evalute indexing information for <full-path>
    -p <path>   Evalute permissions information for <path> (run as file owner!)
    -n  Do not reveal the resulting package in the Finder
    -f <path>   Write the diagnostic to the specified path.
    -r  Avoid restricted operations such as 'heap'.
    -s  Skip gathering system.log.
    -v  Prints version of mddiagnose.
    -m  Minimal report, does not run performance tools or gather system logs
MDDIAGNOSE(8)             BSD System Manager's Manual            MDDIAGNOSE(8)

NAME
     mddiagnose -- gather information to aid in diagnosing Spotlight issues

SYNOPSIS
     mddiagnose -h
     mddiagnose [-f path] [-e path] [-p path] [-n]

DESCRIPTION
     The mddiagnose tool gathers system and Spotlight information in order to assist Apple when investigating issues related to Spotlight. A great deal of information is harvested, spanning system state, system and
     Spotlight details.

   What mddiagnose Collects:
           o   A spindump of the system
           o   Several seconds of top output
           o   Individual samples of mds and mdworker
           o   Paths for all files used by Spotlight to contain its database on every volume
           o   All system logs
           o   All spin and crash reports for the following processes:
                  mds
                  mdworker

           o   Recent spin and crash reports for the following processes, for all local users:
                  mds
                  mdworker

           o   The query text and result quality statistics for recent Spotlight searches.  The actual results of the searches are not gathered
           o   General information about disks and mounted network shares
           o   The path of the last file indexed by each mdworker process on behalf of Spotlight.  The path of the last file which resulted in a crash of an mdworker process.  In each case, only the path is gath-
               ered, not the contents of the file
           o   Spotlight configuration for each volume currently mounted on your system.  This includes the path and size of all files used internally by Spotlight as well as a listing of paths that are user
               excluded from indexing
           o   Comprehensive information about internal state of Spotlight

   What mddiagnose Doesn't Collect:
           o   No user data is harvested from any volume
           o   No paths or files found by any search are returned
           o   No database storage or user files are returned
           o   No authentication credentials are harvested from the system

OPTIONS
     -h      Print full usage.
     -m      Gather a subset of the normal report.
     -f path Write the diagnostic to the specified path.
     -p path Gather Spotlight permissions and filter information.  Run as owner of that file.

EXIT STATUS
     mddiagnose exits with status 0 if there were no internal errors encountered during the diagnostic, or >0 when an error unrelated to external state occurs or unusable input is provided by the user.

Mac OS X                         15 March 2011                        Mac OS X

@elnappo
Copy link
Contributor Author

elnappo commented Nov 5, 2016

caffeinate

Is there a better option to provide subcommand completion as complete -c caffeinate -x -a '(__fish_complete_subcommand)' e.g. caffeinate -i make?

usage: caffeinate [-disu] [-t timeout] [-w Process ID] [command arguments...]
CAFFEINATE(8)             BSD System Manager's Manual            CAFFEINATE(8)

NAME
     caffeinate -- prevent the system from sleeping on behalf of a utility

SYNOPSIS
     caffeinate [-disu] [-t timeout] [-w pid] [utility arguments...]

DESCRIPTION
     caffeinate creates assertions to alter system sleep behavior.  If no assertion flags are specified, caffeinate creates an assertion to prevent idle sleep.  If a utility is specified, caffeinate creates the
     assertions on the utility's behalf, and those assertions will persist for the duration of the utility's execution. Otherwise, caffeinate creates the assertions directly, and those assertions will persist until
     caffeinate exits.

     Available options:

     -d      Create an assertion to prevent the display from sleeping.

     -i      Create an assertion to prevent the system from idle sleeping.

     -m      Create an assertion to prevent the disk from idle sleeping.

     -s      Create an assertion to prevent the system from sleeping. This assertion is valid only when system is running on AC power.

     -u      Create an assertion to declare that user is active. If the display is off, this option turns the display on and prevents the display from going into idle sleep. If a timeout is not specified with '-t'
             option, then this assertion is taken with a default of 5 second timeout.

     -t      Specifies the timeout value in seconds for which this assertion has to be valid. The assertion is dropped after the specified timeout. Timeout value is not used when an utility is invoked with this
             command.

     -w      Waits for the process with the specified pid to exit. Once the the process exits, the assertion is also released.  This option is ignored when used with utility option.

EXAMPLE
     caffeinate -i make
        caffeinate forks a process, execs "make" in it, and holds an assertion that prevents idle sleep as long as that process is running.

SEE ALSO
     pmset(1)

LOCATION
     /usr/bin/caffeinate

Darwin                         November 9, 2012                         Darwin

@faho
Copy link
Member

faho commented Nov 5, 2016

Is there a better option to provide subcommand completion as complete -c caffeinate -x -a '(__fish_complete_subcommand)' e.g. caffeinate -i make?

Nope, that's our current solution.

@floam
Copy link
Member

floam commented Nov 6, 2016

I love these.

Do you want to see this pulled in soon or are you hoping to get the completions from #3525 in first?

@elnappo
Copy link
Contributor Author

elnappo commented Nov 6, 2016

@faho sudo completion does this (with tab completion for subcommands)

complete -c sudo -d "Command to run" -x -a "(__fish_complete_subcommand_root -u -g)"
# Since sudo runs subcommands, it can accept any switches
complete -c sudo -u

The -u flag is not mentioned in the complete manpage.

@floam Would be nice to see these merged soon, I'm on vacation next week. I will open a new pull request if the next batch of completions is ready.

@floam floam merged commit 7a1146e into fish-shell:master Nov 6, 2016
@faho
Copy link
Member

faho commented Nov 6, 2016

The -u flag is not mentioned in the complete manpage.

Ah yes. That's "--unauthoritative", which means the completions aren't complete. The opposite is "-A" or "--authoritative", which would allow us to mark any token not in the completions as an error. These were removed from the docs, but it appears there's still some stuff in the parser that just ends up not doing anything.

For now, just ignore it.

@floam
Copy link
Member

floam commented Nov 6, 2016

Something I noticed after committing was most of these which don't take file arguments are initially showing files in the current directory after command <TAB>.

@elnappo
Copy link
Contributor Author

elnappo commented Nov 6, 2016

@floam which ones? caffeinate completes files but if you provide the first letter of a command it completes only commands. I see this with e.g. mdfind how do I prevent this? I tried complete -c mdfind -x? What is the recommended way to prevent file completion?

@faho
Copy link
Member

faho commented Nov 6, 2016

Currently it's a bit tough - suppressing file completion only works when you offer a completion and all applicable completions have "-f" or "-x". See #112.

@floam
Copy link
Member

floam commented Nov 6, 2016

Doesn't all of his completions have either -f or -x? -- I know we make this work for some completions but it's not immediately obvious to me what is wrong.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants