prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Double requests for documentHighlight
  I've noticed that setting a cursor on some symbol makes the `documentHighlight` underline blink once.
  
  Checked logs and saw the request being made twice on each cursor movement:
  ```
  :: --> pyls textDocument/documentHighlight(12): {'textDocument': {'uri': 'file:////LSP/plugin/highlights.py'}, 'position': {'character': 8, 'line': 38}}
  :: --> pyls textDocument/documentHighlight(13): {'textDocument': {'uri': 'file:////LSP/plugin/highlights.py'}, 'position': {'character': 8, 'line': 38}}
  ```
  
  Then added log in `DocumentHighlightListener` class, inside `on_selection_modified_async` method and that listener seems to be triggered twice on cursor movement. Tested with `print(self.view.file_name())`.
  
  </issue>
  <code>
  [start of plugin/highlights.py]
  1 import sublime
  2 from .core.protocol import Request, Range, DocumentHighlightKind
  3 from .core.registry import LSPViewEventListener
  4 from .core.settings import settings
  5 from .core.typing import List, Dict, Optional
  6 from .core.views import range_to_region, text_document_position_params
  7 from .core.windows import debounced
  8 
  9 SUBLIME_WORD_MASK = 515
  10 NO_HIGHLIGHT_SCOPES = 'comment, string'
  11 
  12 _kind2name = {
  13     DocumentHighlightKind.Unknown: "unknown",
  14     DocumentHighlightKind.Text: "text",
  15     DocumentHighlightKind.Read: "read",
  16     DocumentHighlightKind.Write: "write"
  17 }
  18 
  19 
  20 def remove_highlights(view: sublime.View) -> None:
  21     for kind in settings.document_highlight_scopes.keys():
  22         view.erase_regions("lsp_highlight_{}".format(kind))
  23 
  24 
  25 class DocumentHighlightListener(LSPViewEventListener):
  26     def __init__(self, view: sublime.View) -> None:
  27         super().__init__(view)
  28         self._initialized = False
  29         self._enabled = False
  30         self._stored_point = -1
  31 
  32     @classmethod
  33     def is_applicable(cls, view_settings: dict) -> bool:
  34         if 'documentHighlight' in settings.disabled_capabilities:
  35             return False
  36         return cls.has_supported_syntax(view_settings)
  37 
  38     def on_selection_modified_async(self) -> None:
  39         if not self._initialized:
  40             self._initialize()
  41         if self._enabled and settings.document_highlight_style:
  42             try:
  43                 current_point = self.view.sel()[0].begin()
  44             except IndexError:
  45                 return
  46             self._stored_point = current_point
  47             self._clear_regions()
  48             debounced(self._on_document_highlight, 500, lambda: self._stored_point == current_point, async_thread=True)
  49 
  50     def _initialize(self) -> None:
  51         self._initialized = True
  52         session = self.session("documentHighlightProvider")
  53         if session:
  54             self._enabled = True
  55 
  56     def _clear_regions(self) -> None:
  57         for kind in settings.document_highlight_scopes.keys():
  58             self.view.erase_regions("lsp_highlight_{}".format(kind))
  59 
  60     def _on_document_highlight(self) -> None:
  61         self._clear_regions()
  62         if len(self.view.sel()) != 1:
  63             return
  64         point = self.view.sel()[0].begin()
  65         word_at_sel = self.view.classify(point)
  66         if word_at_sel & SUBLIME_WORD_MASK:
  67             if self.view.match_selector(point, NO_HIGHLIGHT_SCOPES):
  68                 return
  69             session = self.session("documentHighlightProvider", point)
  70             if session:
  71                 params = text_document_position_params(self.view, point)
  72                 request = Request.documentHighlight(params)
  73                 session.send_request(request, self._handle_response)
  74 
  75     def _handle_response(self, response: Optional[List]) -> None:
  76         if not response:
  77             return
  78         kind2regions = {}  # type: Dict[str, List[sublime.Region]]
  79         for kind in range(0, 4):
  80             kind2regions[_kind2name[kind]] = []
  81         for highlight in response:
  82             r = range_to_region(Range.from_lsp(highlight["range"]), self.view)
  83             kind = highlight.get("kind", DocumentHighlightKind.Unknown)
  84             if kind is not None:
  85                 kind2regions[_kind2name[kind]].append(r)
  86         if settings.document_highlight_style == "fill":
  87             flags = 0
  88         elif settings.document_highlight_style == "box":
  89             flags = sublime.DRAW_NO_FILL
  90         else:
  91             flags = sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE
  92             if settings.document_highlight_style == "underline":
  93                 flags |= sublime.DRAW_SOLID_UNDERLINE
  94             elif settings.document_highlight_style == "stippled":
  95                 flags |= sublime.DRAW_STIPPLED_UNDERLINE
  96             elif settings.document_highlight_style == "squiggly":
  97                 flags |= sublime.DRAW_SQUIGGLY_UNDERLINE
  98 
  99         self._clear_regions()
  100         for kind_str, regions in kind2regions.items():
  101             if regions:
  102                 scope = settings.document_highlight_scopes.get(kind_str, None)
  103                 if scope:
  104                     self.view.add_regions("lsp_highlight_{}".format(kind_str),
  105                                           regions, scope=scope, flags=flags)
  106
  [end of plugin/highlights.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/plugin/highlights.py b/plugin/highlights.py
  --- a/plugin/highlights.py
  +++ b/plugin/highlights.py
  @@ -43,9 +43,11 @@
                   current_point = self.view.sel()[0].begin()
               except IndexError:
                   return
  -            self._stored_point = current_point
               self._clear_regions()
  -            debounced(self._on_document_highlight, 500, lambda: self._stored_point == current_point, async_thread=True)
  +            if self._stored_point != current_point:
  +                self._stored_point = current_point
  +                debounced(self._on_document_highlight, 500, lambda: self._stored_point == current_point,
  +                          async_thread=True)
   
       def _initialize(self) -> None:
           self._initialized = True
  
verification_info: {"golden_diff": "diff --git a/plugin/highlights.py b/plugin/highlights.py\n--- a/plugin/highlights.py\n+++ b/plugin/highlights.py\n@@ -43,9 +43,11 @@\n                 current_point = self.view.sel()[0].begin()\n             except IndexError:\n                 return\n-            self._stored_point = current_point\n             self._clear_regions()\n-            debounced(self._on_document_highlight, 500, lambda: self._stored_point == current_point, async_thread=True)\n+            if self._stored_point != current_point:\n+                self._stored_point = current_point\n+                debounced(self._on_document_highlight, 500, lambda: self._stored_point == current_point,\n+                          async_thread=True)\n \n     def _initialize(self) -> None:\n         self._initialized = True\n", "issue": "Double requests for documentHighlight\nI've noticed that setting a cursor on some symbol makes the `documentHighlight` underline blink once.\r\n\r\nChecked logs and saw the request being made twice on each cursor movement:\r\n```\r\n:: --> pyls textDocument/documentHighlight(12): {'textDocument': {'uri': 'file:////LSP/plugin/highlights.py'}, 'position': {'character': 8, 'line': 38}}\r\n:: --> pyls textDocument/documentHighlight(13): {'textDocument': {'uri': 'file:////LSP/plugin/highlights.py'}, 'position': {'character': 8, 'line': 38}}\r\n```\r\n\r\nThen added log in `DocumentHighlightListener` class, inside `on_selection_modified_async` method and that listener seems to be triggered twice on cursor movement. Tested with `print(self.view.file_name())`.\n", "before_files": [{"content": "import sublime\nfrom .core.protocol import Request, Range, DocumentHighlightKind\nfrom .core.registry import LSPViewEventListener\nfrom .core.settings import settings\nfrom .core.typing import List, Dict, Optional\nfrom .core.views import range_to_region, text_document_position_params\nfrom .core.windows import debounced\n\nSUBLIME_WORD_MASK = 515\nNO_HIGHLIGHT_SCOPES = 'comment, string'\n\n_kind2name = {\n    DocumentHighlightKind.Unknown: \"unknown\",\n    DocumentHighlightKind.Text: \"text\",\n    DocumentHighlightKind.Read: \"read\",\n    DocumentHighlightKind.Write: \"write\"\n}\n\n\ndef remove_highlights(view: sublime.View) -> None:\n    for kind in settings.document_highlight_scopes.keys():\n        view.erase_regions(\"lsp_highlight_{}\".format(kind))\n\n\nclass DocumentHighlightListener(LSPViewEventListener):\n    def __init__(self, view: sublime.View) -> None:\n        super().__init__(view)\n        self._initialized = False\n        self._enabled = False\n        self._stored_point = -1\n\n    @classmethod\n    def is_applicable(cls, view_settings: dict) -> bool:\n        if 'documentHighlight' in settings.disabled_capabilities:\n            return False\n        return cls.has_supported_syntax(view_settings)\n\n    def on_selection_modified_async(self) -> None:\n        if not self._initialized:\n            self._initialize()\n        if self._enabled and settings.document_highlight_style:\n            try:\n                current_point = self.view.sel()[0].begin()\n            except IndexError:\n                return\n            self._stored_point = current_point\n            self._clear_regions()\n            debounced(self._on_document_highlight, 500, lambda: self._stored_point == current_point, async_thread=True)\n\n    def _initialize(self) -> None:\n        self._initialized = True\n        session = self.session(\"documentHighlightProvider\")\n        if session:\n            self._enabled = True\n\n    def _clear_regions(self) -> None:\n        for kind in settings.document_highlight_scopes.keys():\n            self.view.erase_regions(\"lsp_highlight_{}\".format(kind))\n\n    def _on_document_highlight(self) -> None:\n        self._clear_regions()\n        if len(self.view.sel()) != 1:\n            return\n        point = self.view.sel()[0].begin()\n        word_at_sel = self.view.classify(point)\n        if word_at_sel & SUBLIME_WORD_MASK:\n            if self.view.match_selector(point, NO_HIGHLIGHT_SCOPES):\n                return\n            session = self.session(\"documentHighlightProvider\", point)\n            if session:\n                params = text_document_position_params(self.view, point)\n                request = Request.documentHighlight(params)\n                session.send_request(request, self._handle_response)\n\n    def _handle_response(self, response: Optional[List]) -> None:\n        if not response:\n            return\n        kind2regions = {}  # type: Dict[str, List[sublime.Region]]\n        for kind in range(0, 4):\n            kind2regions[_kind2name[kind]] = []\n        for highlight in response:\n            r = range_to_region(Range.from_lsp(highlight[\"range\"]), self.view)\n            kind = highlight.get(\"kind\", DocumentHighlightKind.Unknown)\n            if kind is not None:\n                kind2regions[_kind2name[kind]].append(r)\n        if settings.document_highlight_style == \"fill\":\n            flags = 0\n        elif settings.document_highlight_style == \"box\":\n            flags = sublime.DRAW_NO_FILL\n        else:\n            flags = sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE\n            if settings.document_highlight_style == \"underline\":\n                flags |= sublime.DRAW_SOLID_UNDERLINE\n            elif settings.document_highlight_style == \"stippled\":\n                flags |= sublime.DRAW_STIPPLED_UNDERLINE\n            elif settings.document_highlight_style == \"squiggly\":\n                flags |= sublime.DRAW_SQUIGGLY_UNDERLINE\n\n        self._clear_regions()\n        for kind_str, regions in kind2regions.items():\n            if regions:\n                scope = settings.document_highlight_scopes.get(kind_str, None)\n                if scope:\n                    self.view.add_regions(\"lsp_highlight_{}\".format(kind_str),\n                                          regions, scope=scope, flags=flags)\n", "path": "plugin/highlights.py"}]}