From b07ada1255b74c25fbc96901f2b77dc4bd81de1a Mon Sep 17 00:00:00 2001
From: Matthew Martin <phy1729@gmail.com>
Date: Fri, 15 Dec 2017 20:09:39 -0600
Subject: [PATCH] driver: Run under emulate -L zsh and add zsyh_user_options

---
 docs/highlighters.md                   |  8 +++++++
 highlighters/main/main-highlighter.zsh | 31 +++++---------------------
 zsh-syntax-highlighting.zsh            | 19 +++++++++++++++-
 3 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/docs/highlighters.md b/docs/highlighters.md
index c0f79bc..642d2bd 100644
--- a/docs/highlighters.md
+++ b/docs/highlighters.md
@@ -78,6 +78,14 @@ To create your own `acme` highlighter:
           _zsh_highlight_add_highlight 0 $#BUFFER acme:aurora
         }
 
+  If you need to test which options the user has set, test `zsyh_user_options`
+  with a sensible default if the option is not present in supported zsh
+  versions. For example:
+
+        [[ ${zsyh_user_options[ignoreclosebraces]:-off} == on ]]
+
+  The option name must be all lowercase with no underscores and not an alias.
+
 * Name your own functions and global variables `_zsh_highlight_acme_*`.
 
     - In zsh-syntax-highlighting 0.4.0 and earlier, the entrypoints 
diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh
index 3171c20..f7abee8 100644
--- a/highlighters/main/main-highlighter.zsh
+++ b/highlighters/main/main-highlighter.zsh
@@ -195,24 +195,7 @@ _zsh_highlight_main__stack_pop() {
 # Main syntax highlighting function.
 _zsh_highlight_highlighter_main_paint()
 {
-  # Before we even 'emulate -L', save the user's options
-  local -A useroptions
-  if zmodload -e zsh/parameter; then
-    useroptions=("${(@kv)options}")
-  else
-    local canonicaloptions onoff option rawoptions
-    rawoptions=(${(f)"$(emulate -R zsh; set -o)"})
-    canonicaloptions=(${${${(M)rawoptions:#*off}%% *}#no} ${${(M)rawoptions:#*on}%% *})
-    for option in $canonicaloptions; do
-      [[ -o $option ]]
-      # This variable cannot be eliminated c.f. workers/42101.
-      onoff=${${=:-off on}[2-$?]}
-      useroptions+=($option $onoff)
-    done
-  fi
-
-  emulate -L zsh
-  setopt localoptions extendedglob bareglobqual
+  setopt localoptions extendedglob
 
   # At the PS3 prompt and in vared, highlight nothing.
   #
@@ -243,13 +226,13 @@ _zsh_highlight_highlighter_main_paint()
   # ":" for 'then'
   local braces_stack
 
-  if [[ $useroptions[ignorebraces] == on || ${useroptions[ignoreclosebraces]:-off} == on ]]; then
+  if [[ $zsyh_user_options[ignorebraces] == on || ${zsyh_user_options[ignoreclosebraces]:-off} == on ]]; then
     local right_brace_is_recognised_everywhere=false
   else
     local right_brace_is_recognised_everywhere=true
   fi
 
-  if [[ $useroptions[pathdirs] == on ]]; then
+  if [[ $zsyh_user_options[pathdirs] == on ]]; then
     options_to_set+=( PATH_DIRS )
   fi
 
@@ -326,7 +309,7 @@ _zsh_highlight_highlighter_main_paint()
   # Processing buffer
   local proc_buf="$buf"
   local -a args
-  if [[ $useroptions[interactivecomments] == on ]]; then
+  if [[ $zsyh_user_options[interactivecomments] == on ]]; then
     args=(${(zZ+c+)buf})
   else
     args=(${(z)buf})
@@ -420,7 +403,7 @@ _zsh_highlight_highlighter_main_paint()
     # Handle the INTERACTIVE_COMMENTS option.
     #
     # We use the (Z+c+) flag so the entire comment is presented as one token in $arg.
-    if [[ $useroptions[interactivecomments] == on && $arg[1] == $histchars[3] ]]; then
+    if [[ $zsyh_user_options[interactivecomments] == on && $arg[1] == $histchars[3] ]]; then
       if [[ $this_word == *(':regular:'|':start:')* ]]; then
         style=comment
       else
@@ -659,7 +642,7 @@ _zsh_highlight_highlighter_main_paint()
                    _zsh_highlight_main__stack_pop 'R' style=reserved-word
                  fi;;
         $'\x28\x29') # possibly a function definition
-                 if [[ $useroptions[multifuncdef] == on ]] || false # TODO: or if the previous word was a command word
+                 if [[ $zsyh_user_options[multifuncdef] == on ]] || false # TODO: or if the previous word was a command word
                  then
                    next_word+=':start:'
                  fi
@@ -816,7 +799,6 @@ _zsh_highlight_main_highlighter_check_path()
 # Highlight special chars inside double-quoted strings
 _zsh_highlight_main_highlighter_highlight_string()
 {
-  setopt localoptions noksharrays
   local -a match mbegin mend
   local MATCH; integer MBEGIN MEND
   local i j k style
@@ -872,7 +854,6 @@ _zsh_highlight_main_highlighter_highlight_string()
 # Highlight special chars inside dollar-quoted strings
 _zsh_highlight_main_highlighter_highlight_dollar_string()
 {
-  setopt localoptions noksharrays
   local -a match mbegin mend
   local MATCH; integer MBEGIN MEND
   local i j k style
diff --git a/zsh-syntax-highlighting.zsh b/zsh-syntax-highlighting.zsh
index e4e44fa..d100edb 100644
--- a/zsh-syntax-highlighting.zsh
+++ b/zsh-syntax-highlighting.zsh
@@ -83,8 +83,25 @@ _zsh_highlight()
     return $ret
   fi
 
+  # Before we 'emulate -L', save the user's options
+  local -A zsyh_user_options
+  if zmodload -e zsh/parameter; then
+    zsyh_user_options=("${(@kv)options}")
+  else
+    local canonical_options onoff option raw_options
+    raw_options=(${(f)"$(emulate -R zsh; set -o)"})
+    canonical_options=(${${${(M)raw_options:#*off}%% *}#no} ${${(M)raw_options:#*on}%% *})
+    for option in $canonical_options; do
+      [[ -o $option ]]
+      # This variable cannot be eliminated c.f. workers/42101.
+      onoff=${${=:-off on}[2-$?]}
+      zsyh_user_options+=($option $onoff)
+    done
+  fi
+  typeset -r zsyh_user_options
+
+  emulate -L zsh
   setopt localoptions warncreateglobal
-  setopt localoptions noksharrays
   local REPLY # don't leak $REPLY into global scope
 
   # Do not highlight if there are more than 300 chars in the buffer. It's most