Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] completion: add _firefox, _chromium, etc



per w/54888, reworked the browser completion functions:

- remove _mozilla
- strip obsolete browsers from _webbrowser, add some more current ones
- add _firefox to cover firefox and its forks
- add _chromium to cover chromium and its forks

these are probably more elaborate than they need to be, oh well

firefox is one of several applications i've run into with case- and
hyphen-insensitive options. handling these reliably is really annoying.
not sure if annoying enough to do something about it

dana


diff --git a/Completion/Unix/Command/_webbrowser b/Completion/Unix/Command/_webbrowser
index e4f5fe092..17a98669a 100644
--- a/Completion/Unix/Command/_webbrowser
+++ b/Completion/Unix/Command/_webbrowser
@@ -1,3 +1,3 @@
-#compdef amaya arena chimera dillo dwb express galeon grail gzilla hotjava konqueror light mmm Mosaic netrik opera opera-next retawq skipstone www xmosaic zen
+#compdef dillo eolie epiphany falkon konqueror ladybird netrik
 
 _alternative 'files: :_files' 'urls: :_urls'
diff --git a/Completion/X/Command/_chromium b/Completion/X/Command/_chromium
new file mode 100644
index 000000000..be5e9bab3
--- /dev/null
+++ b/Completion/X/Command/_chromium
@@ -0,0 +1,192 @@
+#compdef chrome chromium google-chrome brave cromite helium helium-browser microsoft-edge opera opera-gx ungoogled-chromium vivaldi -P google-chrome-* brave-* microsoft-edge-* opera-* vivaldi-*
+
+(( $+functions[_chromium_urls] )) ||
+_chromium_urls() {
+  # chromium doesn't allow you to open about: or chrome:// urls from the cli,
+  # except for about:blank
+  _alternative \
+    'files: :_files' \
+    'urls: :_urls' \
+    'urls-about:about page:(about\:blank)'
+}
+
+# complete possible data directories (and, without -0, generic paths). as with
+# firefox, we could try harder to look for the *exact* directory we need, but
+# this is probably fine
+# -0 <name>  instead of completing, insert directories into array <name>
+# -a         use all possible directories instead of service-specific ones
+(( $+functions[_chromium_data_dirs] )) ||
+_chromium_data_dirs() {
+  local cfg=${XDG_CONFIG_HOME:-$HOME/.config}
+  local -a ca_opts expl dirs
+  local -A opth
+
+  zparseopts -A opth -D -F - \
+    {M+:,P+:,q+:,r+:,R+:,S+:}=ca_opts 1 2 J: o: O: V: x: X: \
+    0: a \
+  || return
+
+  local -a chrome_dirs=(
+    $cfg/google-chrome{,-beta,-unstable,-canary}
+    $HOME/.var/app/com.google.Chrome/config/google-chrome
+    "$HOME/Library/Application Support/Google/Chrome"{,\ Beta,\ Dev,\ Canary}
+  )
+  local -a chromium_dirs=(
+    $cfg/chromium
+    $HOME/snap/chromium/current/.config/chromium
+    $HOME/.var/app/org.chromium.Chromium/config/chromium
+    "$HOME/Library/Application Support/Chromium"
+  )
+  local -a brave_dirs=(
+    $cfg/brave{,-beta,-development,-unstable}
+    $cfg/BraveSoftware/Brave-Browser{,-Beta,-Dev,-Development,-Nightly}
+    $HOME/.var/app/com.brave.Browser/config/BraveSoftware/Brave-Browser
+    "$HOME/Library/Application Support/BraveSoftware/Brave-Browser"{,-Beta,-Dev,-Development,-Nightly}
+  )
+  local -a cromite_dirs=(
+    $cfg/cromite
+  )
+  local -a helium_dirs=(
+    $cfg/net.imput.helium
+    "$HOME/Library/Application Support/net.imput.helium"
+  )
+  local -a edge_dirs=(
+    $cfg/microsoft-edge{,-beta,-dev,-canary}
+    "$HOME/Library/Application Support/Microsoft Edge"{,\ Beta,\ Dev,\ Canary}
+  )
+  local -a opera_gx_dirs=(
+    $cfg/opera-gx
+    $HOME/.var/app/com.opera.opera-gx/config/opera
+    "$HOME/Library/Application Support/com.operasoftware.OperaGX"
+  )
+  local -a opera_dirs=(
+    $cfg/opera{,-beta,-developer}
+    $HOME/.var/app/com.opera.Opera/config/opera
+    "$HOME/Library/Application Support/com.operasoftware.Opera"
+  )
+  local -a vivaldi_dirs=(
+    $cfg/vivaldi{,-snapshot}
+    $HOME/.var/app/com.vivaldi.Vivaldi/config/vivaldi
+    "$HOME/Library/Application Support/Vivaldi"{,\ Snapshot}
+  )
+
+  if (( $+opth[-a] )); then
+    dirs=(
+      $chrome_dirs $chromium_dirs $brave_dirs $cromite_dirs
+      $helium_dirs $edge_dirs $opera_gx_dirs $opera_dirs $vivaldi_dirs
+    )
+
+  else
+    case $service in
+      google*|chrome*)      dirs=( $chrome_dirs ) ;;
+      chromium*|ungoogled*) dirs=( $chromium_dirs ) ;;
+      brave*)               dirs=( $brave_dirs ) ;;
+      cromite*)             dirs=( $cromite_dirs ) ;;
+      helium*)              dirs=( $helium_dirs ) ;;
+      microsoft*|edge*)     dirs=( $edge_dirs ) ;;
+      opera-gx*)            dirs=( $opera_gx_dirs ) ;;
+      opera*)               dirs=( $opera_dirs ) ;;
+      vivaldi*)             dirs=( $vivaldi_dirs ) ;;
+    esac
+  fi
+
+  dirs=( $^dirs/'Local State'(#qN.-) )
+  dirs=( ${dirs:h} )
+  dirs=( ${(u)dirs} )
+
+  (( $+opth[-0] )) && {
+    trap "${opth[-0]}=( ${(j< >)${(@q+)dirs}} )" EXIT
+    return $(( ! $#dirs ))
+  }
+
+  dirs=( ${dirs//:/\:} )
+
+  _describe -t data-directories 'user data directory' \
+    dirs "${(@)ca_opts}" && ret=0
+  _wanted files expl 'user data directory' \
+    _files -/ "${(@)ca_opts}" && ret=0
+
+  return ret
+}
+
+(( $+functions[_chromium_profile_dirs] )) ||
+_chromium_profile_dirs() {
+  local -a ca_opts cli_dirs dirs profiles disp inst
+  local -A opth
+
+  zparseopts -A opth -D -F - \
+    {1,2,J+:,M+:,o+:,O+:,P+:,q+,r+:,R+:,S+:,V+:,x+:,X+:}=ca_opts \
+    a \
+  || return
+
+  cli_dirs=( ${${(MQ)words:#--user-data-dir=*}#*=} )
+
+  if (( $+opth[-a] )); then
+    _chromium_data_dirs -a0dirs
+    dirs+=( $cli_dirs )
+  else
+    dirs=( $cli_dirs )
+    (( $#dirs )) || _chromium_data_dirs -0dirs
+  fi
+
+  # the name given to a profile by the user has no relationship at all to the
+  # profile's directory name. to make the results meaningful, we'll try to parse
+  # the dirs + names out of the config
+  (( $+commands[python3] )) &&
+  profiles=( ${(f)"$(
+    python3 -c 'if 1:
+      import json, re, sys
+      for st in sys.argv[1:]:
+        with open(st) as f:
+          ps = json.load(f).get("profile", {}).get("info_cache", {})
+          for k, v in ps.items():
+            dir = k
+            nam = v.get("name", "")
+            print(f"{nam}\0{dir}")
+    ' $^dirs/'Local State'(#qN.-)
+  )"} )
+
+  (( $#profiles )) || profiles=( $^dirs/(Default|Profile\ *)(#qN/-:t) )
+
+  disp=( ${${profiles//:/\\:}/$'\0'/:} )
+  inst=( ${profiles#*$'\0'} )
+
+  _describe -t profiles 'profile directory' disp inst "${(@)ca_opts}"
+}
+
+# chromium has hundreds of options, largely undocumented and apparently
+# unstable. we make no attempt to support them all. these are the ones i found
+# to be most commonly referenced
+local -a args=(
+  + '(excl)'
+  '(- : *)--version[display version information]'
+
+  + '(open)'
+  '--incognito[open new Incognito window or tab]'
+  '--new-tab[open new tab]'
+  '--new-window[open new window]'
+
+  + '(proxy)'
+  '--proxy-server=-[specify proxy server]:proxy server:{
+    compset -P "(http|socks|socks4|socks5)\://"
+    _hosts "${(@)expl}"
+  }'
+  '--no-proxy-server[disable proxy server]'
+  '--proxy-auto-detect[auto-detect proxy configuration]'
+  # @todo this has to be http://, https://, or data:
+  '--proxy-pac-url=-[specify proxy auto-configuration URL]:PAC-file URL:_urls'
+
+  + misc
+  '(*)--app=-[open specified URL in app mode]: :_chromium_urls'
+  '--password-store=-[specify password storage back-end]:password store:(
+    basic gnome gnome-libsecret kwallet kwallet5 kwallet6
+  )'
+  '--user-data-dir=-[specify user data directory]: :_chromium_data_dirs -a'
+  '--profile-directory=-[specify profile directory]: :_chromium_profile_dirs'
+  '(--app)*: :_chromium_urls'
+)
+
+[[ $service == (microsoft|edge)* ]] &&
+args=( ${${args//incognito/inprivate}//Incognito/InPrivate} )
+
+_arguments -s -S : $args
diff --git a/Completion/X/Command/_firefox b/Completion/X/Command/_firefox
new file mode 100644
index 000000000..704fc7c64
--- /dev/null
+++ b/Completion/X/Command/_firefox
@@ -0,0 +1,328 @@
+#compdef firefox mozilla-firefox=firefox floorp librewolf mullvad-browser mullvadbrowser palemoon tor-browser torbrowser waterfox zen zen-browser -P firefox*
+
+(( $+functions[_firefox_urls] )) ||
+_firefox_urls() {
+  if compset -P about:; then
+    _describe -t urls-about 'about page' '(
+      about addons buildconfig cache certificate checkerboard compat
+      config crashes credits debugging downloads firefoxview home
+      keyboard license logging logins loginsimportreport logo memory
+      mozilla networking newtab policies preferences privatebrowsing
+      processes profiles profiling protections rights robots
+      serviceworkers studies support sync-log telemetry translations
+      unloads url-classifier webauthn webrtc welcome
+    )'
+  elif compset -P mailto:; then
+    _email_addresses -c
+  else
+    _alternative 'files: :_files' 'urls: :_urls'
+  fi
+}
+
+# complete possible config directories. we could try harder to look for the
+# *exact* directory we need, but this should work in most cases
+# -0 <name>  instead of completing, insert directories into array <name>
+# -a         use all possible directories instead of service-specific ones
+(( $+functions[_firefox_config_dirs] )) ||
+_firefox_config_dirs() {
+  local cfg=${XDG_CONFIG_HOME:-$HOME/.config}
+  local -a ca_opts dirs
+  local -A opth
+
+  zparseopts -A opth -D -F - \
+    {1,2,J+:,M+:,o+:,O+:,P+:,q+,r+:,R+:,S+:,V+:,x+:,X+:}=ca_opts \
+    0: a \
+  || return
+
+  local -a firefox_dirs=(
+    $cfg/mozilla/firefox
+    $HOME/.mozilla/firefox
+    $HOME/.var/app/org.mozilla.firefox/.mozilla/firefox
+    $HOME/snap/firefox/common/.mozilla/firefox
+    "$HOME/Library/Application Support/Firefox"
+  )
+  local -a floorp_dirs=(
+    $cfg/floorp/floorp # unverified
+    $HOME/.floorp
+    $HOME/.var/app/one.ablaze.floorp/.floorp
+    "$HOME/Library/Application Support/Floorp"
+  )
+  local -a librewolf_dirs=(
+    $cfg/librewolf/librewolf
+    $HOME/.librewolf
+    $HOME/.var/app/io.gitlab.librewolf-community/.librewolf
+    "$HOME/Library/Application Support/librewolf"
+  )
+  local -a mullvad_dirs=(
+    # based on tor browser, probably works similar
+    $HOME/.var/app/net.mullvad.MullvadBrowser/.mullvad-browser/.mullvad/mullvadbrowser
+    "$HOME/Library/Application Support/MullvadBrowser"
+  )
+  local -a palemoon_dirs=(
+    "$HOME/.moonchild productions/pale moon"
+    "$HOME/Library/Application Support/Pale Moon"
+  )
+  local -a tor_dirs=(
+    # i think on linux the ~/.mozilla equivalent normally lives inside the same
+    # directory the browser is installed to? but i couldn't verify
+    "$HOME/Library/Application Support/TorBrowser-Data/Browser"
+  )
+  local -a waterfox_dirs=(
+    $cfg/waterfox/waterfox # unverified
+    $HOME/.waterfox
+    $HOME/.var/app/net.waterfox.waterfox/.waterfox
+    "$HOME/Library/Application Support/Waterfox"
+  )
+  local -a zen_dirs=(
+    $cfg/zen/zen
+    $HOME/.zen
+    $HOME/.var/app/app.zen_browser.zen/.zen
+    $HOME/.var/app/io.github.zen_browser.zen/.zen
+    "$HOME/Library/Application Support/zen"
+  )
+
+  if (( $+opth[-a] )); then
+    dirs=(
+      $firefox_dirs $floorp_dirs $librewolf_dirs $mullvad_dirs
+      $palemoon_dirs $tor_dirs $waterfox_dirs $zen_dirs
+    )
+  else
+    case $service in
+      firefox*)   dirs=( $firefox_dirs ) ;;
+      floorp*)    dirs=( $floorp_dirs ) ;;
+      librewolf*) dirs=( $librewolf_dirs ) ;;
+      mullvad*)   dirs=( $mullvad_dirs ) ;;
+      palemoon*)  dirs=( $palemoon_dirs ) ;;
+      tor*)       dirs=( $tor_dirs ) ;;
+      waterfox*)  dirs=( $waterfox_dirs ) ;;
+      zen*)       dirs=( $zen_dirs ) ;;
+    esac
+  fi
+
+  dirs=( $^dirs/profiles.ini(#qN.-) )
+  dirs=( ${dirs:h} )
+  dirs=( ${(u)dirs} )
+
+  (( $+opth[-0] )) && {
+    trap "${opth[-0]}=( ${(j< >)${(@q+)dirs}} )" EXIT
+    return $(( ! $#dirs ))
+  }
+
+  dirs=( ${dirs//:/\:} )
+
+  _describe -t profile-directories 'profile directory' dirs "${(@)ca_opts}"
+}
+
+# complete old-style ToolkitProfileService profiles
+# -0 <name>  instead of completing, insert NUL-separated name/path pairs into
+#            array <name>
+# -a         see _firefox_profile_dirs
+(( $+functions[_firefox_toolkit_profiles] )) ||
+_firefox_toolkit_profiles() {
+  local dir
+  local -a ca_opts tmp dirs profiles
+  local -A opth
+
+  zparseopts -A opth -D -F - \
+    {1,2,J+:,M+:,o+:,O+:,P+:,q+,r+:,R+:,S+:,V+:,x+:,X+:}=ca_opts \
+    0: a \
+  || return
+
+  _firefox_config_dirs ${opth[-a]+-a} -0dirs
+
+  # if we don't care about the paths we can use a simpler method
+  if (( ! $+opth[-0] )); then
+    for dir in $dirs; do
+      tmp=( ${(f)"$( < $dir/profiles.ini )"} )
+      tmp=( ${(M)tmp:#[[:space:]]#Name=*} )
+      tmp=( ${tmp#*=} )
+      profiles+=( $tmp )
+    done
+
+  elif (( $+commands[python3] )); then
+    profiles=( ${(f)"$(
+      python3 -c 'if 1:
+        import configparser, re, sys
+        for dir in sys.argv[1:]:
+          cfg = configparser.ConfigParser()
+          cfg.read(f"{dir}/profiles.ini")
+          for sct in cfg.sections():
+            if not sct.startswith("Profile") or not cfg[sct].get("Name"):
+              continue
+            name = cfg[sct].get("Name")
+            path = cfg[sct].get("Path")
+            # ignore Windows path
+            if "/" not in path and "\\" in path:
+              continue
+            if cfg[sct].get("IsRelative") == "1":
+              path = f"{dir}/{path}"
+            print(f"{name}\0{path}")
+      ' $dirs
+    )"} )
+  fi
+
+  (( $+opth[-0] )) && {
+    trap "${opth[-0]}=( ${(j< >)${(@q+)profiles}} )" EXIT
+    return $(( ! $#profiles ))
+  }
+
+  profiles=( ${profiles%%$'\0'*} )
+  profiles=( ${profiles//:/\:} )
+
+  _describe -t toolkit-profiles 'toolkit profile' profiles "${(@)ca_opts}"
+}
+
+# complete new-style SelectableProfileService profiles
+# -0 <name>  see _firefox_toolkit_profiles
+# -a         see _firefox_toolkit_profiles
+(( $+functions[_firefox_selectable_profiles] )) ||
+_firefox_selectable_profiles() {
+  local dir db
+  local -a ca_opts tmp dirs profiles
+  local -A opth
+
+  zparseopts -A opth -D -F - \
+    {1,2,J+:,M+:,o+:,O+:,P+:,q+,r+:,R+:,S+:,V+:,x+:,X+:}=ca_opts \
+    0: a \
+  || return
+
+  _firefox_config_dirs ${opth[-a]+-a} -0dirs
+
+  (( $+commands[sqlite3] )) &&
+  for dir in $dirs; do
+    # apparently firefox sometimes re-creates these databases, so there can be
+    # more than one in the directory. the active one is stored in preferences,
+    # but we'll just assume it's the newest
+    for db in "$dir/Profile Groups/"*.sqlite(#qN.-om[1]); do
+      tmp+=( ${${(f)"$(
+        sqlite3 -separator $'\x1f' $db 'SELECT name, path FROM Profiles;'
+      )"}//$'\x1f'/$'\0'} )
+      for 1 2 in "${(@0)tmp}"; do
+        [[ $2 != */* && $2 == *\\* ]] && continue # ignore Windows path
+        [[ $2 == /* ]] || 2=${db:h:h}/$2 # make absolute
+        profiles+=( $1$'\0'$2 )
+      done
+    done
+  done
+
+  (( $+opth[-0] )) && {
+    trap "${opth[-0]}=( ${(j< >)${(@q+)profiles}} )" EXIT
+    return $(( ! $#profiles ))
+  }
+
+  profiles=( ${profiles%%$'\0'*} )
+  profiles=( ${profiles//:/\:} )
+
+  _describe -t selectable-profiles 'selectable profile' profiles "${(@)ca_opts}"
+}
+
+# at time of writing, there's no specific way to use/manage the newer
+# SelectableProfileService profiles from the cli. however, it's possible to load
+# one by giving its path to --profile, which is a common work-around. to make
+# this more convenient, we offer these profile paths in addition to the generic
+# path completion
+# -a  see _firefox_toolkit_profiles
+(( $+functions[_firefox_profile_dirs] )) ||
+_firefox_profile_dirs() {
+  local ret=1
+  local -a ca_opts expl profiles disp inst
+
+  zparseopts -A opth -D -F - \
+    {M+:,P+:,q+:,r+:,R+:,S+:}=ca_opts 1 2 J: o: O: V: x: X: \
+    a \
+  || return
+
+  _firefox_toolkit_profiles ${opth[-a]+-a} -0profiles && {
+    disp=( ${${profiles//:/\\:}/$'\0'/:} )
+    inst=( ${profiles#*$'\0'} )
+    _describe -t toolkit-profiles 'toolkit profile directory' \
+      disp inst "${(@)ca_opts}" && ret=0
+  }
+
+  _firefox_selectable_profiles ${opth[-a]+-a} -0profiles && {
+    disp=( ${${profiles//:/\\:}/$'\0'/:} )
+    inst=( ${profiles#*$'\0'} )
+    _describe -t selectable-profiles 'selectable profile directory' \
+      disp inst "${(@)ca_opts}" && ret=0
+  }
+
+  _wanted files expl 'profile directory' _files -/ "${(@)ca_opts}" && ret=0
+
+  return ret
+}
+
+local x
+local -a match mbegin mend tmp args
+
+tmp=(
+  + '(excl)'
+  '(- : *)'{-h,--help}'[display help information]'
+  '(- : *)'{-v,--version}'[display version information]'
+  '(- : *)--full-version[display version and build information]'
+
+  + '(start)'
+  # not in help output for some reason
+  '--CreateProfile=[create new profile with specified name]:profile name'
+  '-P=[start with profile manager or specified profile]:: :_firefox_toolkit_profiles'
+  '--profile=[start with profile at specified path]: :_firefox_profile_dirs -a'
+  '--migration[start with migration wizard]'
+  '--ProfileManager[start with profile manager]'
+
+  + misc
+  '--g-fatal-warnings[make all warnings fatal]'
+  '--origin-to-force-quic-on=[force to use QUIC for specified origin]: :_urls'
+  '--new-instance[open new instance instead of new window]'
+  '--safe-mode[disable extensions and themes]'
+  '--allow-downgrade[allow downgrading profile]'
+  '--MOZ_LOG=[specify log modules]:log modules'
+  '--MOZ_LOG_FILE=[specify log file]:log file:_files'
+  '--headless[run without GUI]'
+  '--browser[open browser window]'
+  '*--new-window=[open new window (specify URL)]:: :_firefox_urls'
+  '*--new-tab=[open new tab (specify URL)]:: :_firefox_urls'
+  '*--private-window=[open new private window (specify URL)]:: :_firefox_urls'
+  '--preferences[open about\:preferences]'
+  '--screenshot=[save screenshot (specify path)]::screenshot path:_files'
+  '--window-size=[specify width and height of screenshot (with --screenshot)]:screenshot window size (width[,height])'
+  '--search=[search for specified term with default search engine]:search term'
+  '--setDefaultBrowser[set as default browser]'
+  '--first-startup[run post-install actions before opening new window]'
+  '--kiosk[start in kiosk mode]'
+  '--kiosk-monitor=[place kiosk browser window on specified monitor]: :_numbers "monitor number"'
+  '--disable-pinch[disable touch-screen and touch-pad pinch gestures]'
+  '--jsconsole[open Browser Console]'
+  '--devtools[open DevTools on initial load]'
+  '--jsdebugger=[open Browser Toolbox (specify Firefox path)]::Firefox path:_files'
+  '--wait-for-jsdebugger[spin event loop until JS debugger connects (with --jsdebugger)]'
+  '--start-debugger-server=[start devtools server at specified port or socket path]: :{
+    compset -P ws\:
+    _alternative \
+      "ports\: \:_numbers -l1 -m65535 \"port number\"" \
+      "files\:socket path\:_files -g \"(#q=-)\""
+  }'
+  '--marionette[enable remote control server]'
+  '--remote-debugging-port=[start Firefox Remote Agent (specify port)]:: :\
+    _numbers -l1 -m65535 -d9222 "port number"
+  '
+  '--remote-allow-hosts=[specify Host header values to allow for incoming requests (with --remote-debugging-port)]:Host header value:\
+    _sequence -s, _hosts
+  '
+  '--remote-allow-origins=[specify Origin header values to allow for incoming requests (with --remote-debugging-port)]:Origin header value:\
+    _sequence -s, _urls
+  '
+  "--remote-allow-system-access[enable privileged access to application's parent process (with --remote-debugging-port)]"
+
+  '*: :_firefox_urls'
+)
+
+# options support both single and double hyphens. recognise the alternate forms
+for x in $tmp; do
+  args+=( $x )
+  [[ $x == (#b)(|\(*\))(|\*)(--|-)([^-]*) ]] && {
+    [[ $match[3] == - ]] && match[3]=-- || match[3]=-
+    args+=( \!${(j<>)match} )
+  }
+done
+
+# options are also case-insensitive
+_arguments -s -S -M 'm:{A-Za-z}={a-zA-Z} r:|[_-]=* r:|=*' : $args
diff --git a/Completion/X/Command/_mozilla b/Completion/X/Command/_mozilla
deleted file mode 100644
index 0be25b8d3..000000000
--- a/Completion/X/Command/_mozilla
+++ /dev/null
@@ -1,150 +0,0 @@
-#compdef mozilla mozilla-firefox mozilla-xremote-client firefox iceweasel=firefox
-
-local curcontext="$curcontext" state line expl ret=1 suf
-typeset -A opt_args
-
-local popts="-installer -CreateProfile -P -ProfileWizard -ProfileManager -SelectProfile"
-local -a mozopts
-
-if [[ $service = *remote* ]]; then
-  state=remote
-else
-  if [[ $service = *firefox* ]]; then
-    mozopts=(
-    '-browser[open browser window]' \
-    '-console[start with debugging console]' \
-    '-h[output help message]' \
-    '-help[output help message]' \
-    '-inspector[start with DOM Inspector]:URL to inspect:->location' \
-    '-install-global-extension[install an extension]:extension to install:_files' \
-    '-new-window[load URL in new window]:URL to load:->location' \
-    '-new-tab[load URL in new tab]:URL to load:->location' \
-    '-no-remote[run with multiple profiles]' \
-    '-profile[specify profile file]:profile file:_files' \
-    '-v[show version]' \
-    '-version[show version]' \
-    '-safe-mode[disable extensions and themes for this session]'
-    )
-  else
-    mozopts=(
-      "($popts)-installer[start with 4.x migration window]"
-      "($popts)-ProfileWizard[start with profile wizard]"
-      "($popts)-SelectProfile[start with profile selection dialog]"
-      '-splash[enable splash screen]'
-      '-chat[start with IRC client]'
-      '-news[start with news]'
-      '-venkman[start with JavaScript debugger]'
-      '-terminal[start with command line terminal]'
-      '-mail[start with mail]'
-      '-compose[start with messenger compose]:URL:_urls' 
-    )
-  fi
-  _x_arguments -C  $mozopts \
-    '-height[height of startup window]:height' \
-    '(-)'{-h,-help}'[show usage message]' \
-      "($popts)-CreateProfile:profile" \
-    '-width[width of startup window]:width' \
-    '(-)'{-v,-version}'[show the version number and build date]' \
-    "($popts)-P[start with profile]:profile:->profile" \
-    "($popts)-ProfileManager[start with profile manager]" \
-    '-UILocale:locale' \
-    '-contentLocale:locale' \
-    '-remote[execute a command in an existing Mozilla]:remote command:->remote' \
-    '-jsconsole[start with JavaScript Console]' \
-    '-edit[start with editor]:URL:_urls' \
-    '-chrome[load the specified chrome]:URL:_urls' \
-    '*:location:->urls' && ret=0
-fi
-
-[[ "$state" = "urls" ]] &&
-  _files "$@" && return 0
-
-# Handle mozilla remote commands
-if [[ "$state" = "remote" ]]; then  
-  local -a remote_commands
-  remote_commands=(openURL openFile saveAs mailto addBookmark ping)
-
-  compset -P '*\('
-  if compset -S '(|\\)\)*'; then
-    set - -S "" "$@"
-  else
-    set - -S"${${QIPREFIX:+)}:-\)}$compstate[quote] " "$@"
-  fi
-  case $IPREFIX in
-    openURL*)
-      if compset -P "*,"; then
-        _wanted option expl 'option' compadd "$@" new-tab new-window && ret=0
-      else
-        compset -S ',*'
-        state=urls
-      fi
-    ;;
-    addBookmark*) state=urls;;
-    openFile*) _files "$@" -W ~;;
-    saveAs*) 
-      if compset -P "*,"; then
-        _wanted types expl 'data type' \
-            compadd "$@" -M 'm:{a-zA-Z}={A-Za-z}' HTML Text PostScript && ret=0
-      else
-        compset -S ",*" || suf=","
-        _files -qS "$suf" -W ~ && ret=0
-      fi
-    ;;
-    mailto*)
-      _email_addresses -s, -c && ret=0
-    ;;
-    *)
-      compset -S '(|\\)\(*' || suf="${${QIPREFIX:+(}:-\(}"
-      _wanted commands expl 'remote command' \
-          compadd -qS "$suf" -M 'm:{a-zA-Z}={A-Za-z}' -a \
-                  remote_commands && ret=0
-    ;;
-  esac
-fi
-
-if [[ "$state" = "urls" ]]; then
-  # Complete mozilla urls
-  if compset -P about: ; then
-    _wanted values expl 'about what' \
-        compadd "$@" authors blank cache document fonts global hype image-cache \
-            license logo memory-cache mozilla plugins && ret=0
-  elif compset -P news: ; then
-    _newsgroups "$@" && ret=0
-  elif compset -P mailto: ; then
-    _email_addresses -c && ret=0
-  else
-    _tags prefixes
-    while _tags; do
-      while _next_label prefixes expl 'URL prefix' "$@"; do
-        _urls "$expl[@]" && ret=0
-	compset -S '[^:]*'
-        compadd -S '' "$expl[@]" about: news: mailto: mocha: javascript: && ret=0
-      done
-      (( ret )) || return 0
-    done
-  fi
-fi
-
-if [[ $state == "profile" ]]; then
-  if [[ $service == *firefox* ]]; then
-    local -a profiles text profiledir
-    case "$OSTYPE" in
-    darwin*) profiledir=~/"Library/Application Support/Firefox" ;;
-    *)       profiledir=~/.mozilla/firefox/ ;;
-    esac
-    profiles=(${(f)"$(< ${profiledir}/profiles.ini)"})
-    profiles=(${(M)${profiles}:#(\[Profile|(Path|Name)=)*})
-    text=${(F)profiles}
-    profiles=(${(f)text//(#b)\[Profile([0-9]##)\]
-Name=([^
-]##|)
-Path=([^
-]##|)/$match[2]})
-    profiles=(${profiles%:})
-    compadd $profiles
-  else
-    compadd ~/.mozilla/*/*.slt(\:h\:t)
-  fi
-fi
-
-return ret




Messages sorted by: Reverse Date, Date, Thread, Author