From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?utf-8?Q?Jostein_Kj=C3=B8nigsen?= Newsgroups: gmane.emacs.devel Subject: [PATCH] New major-mode: bicep-ts-mode Date: Thu, 21 Dec 2023 15:32:16 +0100 Message-ID: <7121354D-5D04-4B22-A0D3-54C469BF5B85@secure.kjonigsen.net> Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3774.200.91.1.1\)) Content-Type: multipart/alternative; boundary="Apple-Mail=_BE7A6854-61A3-4C97-94B7-FF602F42E545" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="8281"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Yuan Fu , Theodor Thornhill To: "Ergus via Emacs development discussions." Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Dec 21 15:33:23 2023 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rGK6z-0001s0-65 for ged-emacs-devel@m.gmane-mx.org; Thu, 21 Dec 2023 15:33:23 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rGK6M-0006Zg-KQ; Thu, 21 Dec 2023 09:32:42 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rGK6J-0006Z7-P2 for emacs-devel@gnu.org; Thu, 21 Dec 2023 09:32:39 -0500 Original-Received: from wout5-smtp.messagingengine.com ([64.147.123.21]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rGK6F-0007Qc-QS for emacs-devel@gnu.org; Thu, 21 Dec 2023 09:32:38 -0500 Original-Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id B5F623200AF3; Thu, 21 Dec 2023 09:32:30 -0500 (EST) Original-Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Thu, 21 Dec 2023 09:32:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= secure.kjonigsen.net; h=cc:cc:content-type:content-type:date :date:from:from:in-reply-to:message-id:mime-version:reply-to :subject:subject:to:to; s=fm1; t=1703169150; x=1703255550; bh=l/ uBSwFoMmrfE2g1S0P9EPKBn6DZHM2g3rYRd5Ti4rY=; b=pd6j3MTfD6fVxyRoWL x4PT20Oy/fxybw/YtPhvCMaebebSNswL43McjW9mKN/rPkYTdqls0WnB3jFDhsHP NR3QHYTrTxnpOj7TDB4vg6oyS9SPl6bQsrpDmU08irQh+oxSRvAESCeFlr/nsUWL EB67t6isW9PD9hbE/RlCHpPpMcEJHWU4nca+pL8UCVZ6MKkS8axzVL4Hj71vgXgh t/78E/lo1pCqkqxzOYPOkUd0rpwgEbo5NfzEsVrxywRNI6Q230dHtXks+JcHG42D KQoMrSbU++T14pSUXcTl8fGBq5JQBJgc4yCRSC/5b8DfsoQUEWlkH9BPJwxOqOC3 meLQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:message-id :mime-version:reply-to:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1703169150; x=1703255550; bh=l/uBSwFoMmrfE2g1S0P9EPKBn6DZHM2g3rY Rd5Ti4rY=; b=5uXmW9FXGtoOp9mTa5S4TYbdEFVdF8VPASo+8r9G6eWC/6JU/MG XvzELSG0nnLFvrhTKG27x0U2zFNbmLl7gye8b/xdR1N5B8L5z4U4yuPlIB5UcM5p oiUkdI0e1AdGi7IXKBfxGePJFbBfEpKP9/IJkoNE4FPbDeasw0sUJ2JuQTsQMa0J XuOBLT5NQ+U7BtZwPWCnoTe8dXWZ3jCx0bRiHwbyvCLYMKm1XBvCdHttow9YWVOk SSVGUUTccXHQ3vSonuCEq5UC/3H3WH6GNZMcfpTKpOE8/YDLWg13Vhmz0bNh/uB2 Y8DvWPLN7lQicW+krdy5bqKLXm2H3COM7NQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrvdduhedggedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephfgtggfukfffvefvofesrgdtmherhhdtjeenucfhrhhomheplfhoshhtvghi nhcumfhjpphnihhgshgvnhcuoehjohhsthgvihhnsehsvggtuhhrvgdrkhhjohhnihhgsh gvnhdrnhgvtheqnecuggftrfgrthhtvghrnhepvdfgfeehgfetveefheeifeejudevleeg ffethffgieehheekheellefhgeduleetnecuffhomhgrihhnpehgihhthhhusgdrtghomh dpmhhitghrohhsohhfthdrtghomhenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgr mhepmhgrihhlfhhrohhmpehjohhsthgvihhnsehsvggtuhhrvgdrkhhjohhnihhgshgvnh drnhgvth X-ME-Proxy: Feedback-ID: ib2f84088:Fastmail Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 21 Dec 2023 09:32:29 -0500 (EST) X-Mailer: Apple Mail (2.3774.200.91.1.1) Received-SPF: pass client-ip=64.147.123.21; envelope-from=jostein@secure.kjonigsen.net; helo=wout5-smtp.messagingengine.com X-Spam_score_int: -6 X-Spam_score: -0.7 X-Spam_bar: / X-Spam_report: (-0.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, URI_TRY_3LD=1.999 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:314040 Archived-At: --Apple-Mail=_BE7A6854-61A3-4C97-94B7-FF602F42E545 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hey everyone. QUICK PREFACE Currently if one works with Microsoft-oriented solutions (C#, .NET, = TypeScript, Azure, etc) one often also has to work with Bicep. Bicep is = a programming language used to describe Infrastructure-as-Code used for = deploying services in Microsoft Azure cloud. Unfortunately the only editor currently available with useful = Bicep-support is Microsoft VSCode. Working with Bicep in Emacs currently = is not really feasible. The Bicep language itself is a type-safe language with an associated = open-source toolchain, which in turn gets compiled to JSON-formatted = Azure Resource Manager (ARM) templates, which can actually provision = resources in Azure. With appropriate editor-support, working with Bicep is superior to = working with the untyped JSON for ARM template purposes. As such, adding = support for Bicep to Emacs, would mean most Azure-developers can still = stay 100% within Emacs to do their job :) ABOUT THE PATCH The attached patch tries to rectify the situation by making introducing = tree-sitter based major-mode to handle important aspects of Bicep = development: * provide syntax highligting * provide indentation * provide imenu-support The implementation itself depends on tree-sitter and the tree-sitter = grammar developed by Amanda Qureshi (unaffiliated with this effort): https://github.com/amaanq/tree-sitter-bicep This grammar compiles and installs cleanly with the default settings = found in M-x treesit-install-language-grammar given the repo URL only. The implementation is fairly basic, but as far as I can see it works = well and greatly improve the user-experience for Bicep-development. NOT yet provided: * adding Bicep.LangServer LSP-configuration to eglot (although I=E2=80=99v= e tested that locally and it seems to work seamlessly once you have the = Bicep language-server resolved). The latter is essential into bringing Emacs to feature-parity with = VSCode, but its probably best to land this major-mode, before committing = to how that major-mode should be wired up inside Emacs :) Any opinions? For more information about Bicep, Microsoft has documentation online: = https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overv= iew?tabs=3Dbicep Bicep toolchain souce: https://github.com/Azure/bicep =E2=80=94 Kind Regards Jostein Kj=C3=B8nigsen =EF=BF=BC= --Apple-Mail=_BE7A6854-61A3-4C97-94B7-FF602F42E545 Content-Type: multipart/mixed; boundary="Apple-Mail=_63C47C86-BE22-466F-A187-E6864DEEE985" --Apple-Mail=_63C47C86-BE22-466F-A187-E6864DEEE985 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
Hey = everyone.

QUICK = PREFACE

Currently if one works with = Microsoft-oriented solutions (C#, .NET, TypeScript, Azure, etc) one = often also has to work with Bicep. Bicep is a programming language used = to describe Infrastructure-as-Code used for deploying services in = Microsoft Azure cloud.

Unfortunately the = only editor currently available with useful Bicep-support is Microsoft = VSCode. Working with Bicep in Emacs currently is not really = feasible.

The Bicep language itself is a = type-safe language with an associated open-source toolchain, which in = turn gets compiled to JSON-formatted Azure Resource Manager (ARM) = templates, which can actually provision resources in = Azure.

With appropriate editor-support, working = with Bicep is superior to working with the untyped JSON for ARM template = purposes. As such, adding support for Bicep to Emacs, would mean most = Azure-developers can still stay 100% within Emacs to do their job = :)

ABOUT THE PATCH

The = attached patch tries to rectify the situation by making introducing = tree-sitter based major-mode to handle important aspects of Bicep = development:

* provide syntax = highligting
* provide indentation
* provide = imenu-support

The implementation itself depends = on tree-sitter and the tree-sitter grammar developed by Amanda Qureshi = (unaffiliated with this effort):

This grammar = compiles and installs cleanly with the default settings found in M-x = treesit-install-language-grammar given the repo URL = only.

The implementation is fairly basic, but = as far as I can see it works well and greatly improve the = user-experience for Bicep-development.

NOT yet = provided:

* adding Bicep.LangServer = LSP-configuration to eglot (although I=E2=80=99ve tested that locally = and it seems to work seamlessly once you have the Bicep language-server = resolved).

The latter is essential into = bringing Emacs to feature-parity with VSCode, but its probably best to = land this major-mode, before committing to how that major-mode should be = wired up inside Emacs :)


Any = opinions?


For more = information about Bicep, Microsoft has documentation online: https://learn.microsoft.com/en-us/azure/azure-re= source-manager/bicep/overview?tabs=3Dbicep
Bicep toolchain = souce: https://github.com/Azure/bicep=


=E2=80=94
Kind = Regards
Jostein = Kj=C3=B8nigsen

= --Apple-Mail=_63C47C86-BE22-466F-A187-E6864DEEE985 Content-Disposition: attachment; filename=bicep-ts-model.el Content-Type: application/octet-stream; x-unix-mode=0644; name="bicep-ts-model.el" Content-Transfer-Encoding: quoted-printable ;;;=20bicep-ts-mode.el=20---=20tree-sitter=20support=20for=20Bicep=20=20= -*-=20lexical-binding:=20t;=20-*-=0A=0A;;=20Copyright=20(C)=202024-2024=20= Free=20Software=20Foundation,=20Inc.=0A=0A;;=20Author=20=20=20=20=20:=20= Jostein=20Kj=C3=B8nigsen=20=0A;;=20Maintainer=20:=20= Jostein=20Kj=C3=B8nigsen=20=0A;;=20Created=20=20=20= =20:=20December=202023=0A;;=20Keywords=20=20=20:=20bicep=20languages=20= tree-sitter=0A=0A;;=20This=20file=20is=20part=20of=20GNU=20Emacs.=0A=0A= ;;=20GNU=20Emacs=20is=20free=20software:=20you=20can=20redistribute=20it=20= and/or=20modify=0A;;=20it=20under=20the=20terms=20of=20the=20GNU=20= General=20Public=20License=20as=20published=20by=0A;;=20the=20Free=20= Software=20Foundation,=20either=20version=203=20of=20the=20License,=20or=0A= ;;=20(at=20your=20option)=20any=20later=20version.=0A=0A;;=20GNU=20Emacs=20= is=20distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A= ;;=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A;;=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A;;=20GNU=20General=20Public=20= License=20for=20more=20details.=0A=0A;;=20You=20should=20have=20received=20= a=20copy=20of=20the=20GNU=20General=20Public=20License=0A;;=20along=20= with=20GNU=20Emacs.=20=20If=20not,=20see=20= .=0A=0A;;;=20Commentary:=0A;;=0A=0A;;;=20= Code:=0A=0A(require=20'treesit)=0A=0A(declare-function=20= treesit-parser-create=20"treesit.c")=0A(declare-function=20= treesit-induce-sparse-tree=20"treesit.c")=0A(declare-function=20= treesit-node-start=20"treesit.c")=0A(declare-function=20= treesit-node-type=20"treesit.c")=0A(declare-function=20= treesit-node-child=20"treesit.c")=0A(declare-function=20= treesit-node-child-by-field-name=20"treesit.c")=0A=0A(defcustom=20= bicep-ts-mode-indent-offset=202=0A=20=20"Number=20of=20spaces=20for=20= each=20indentation=20step=20in=20`bicep-ts-mode'."=0A=20=20:version=20= "29.1"=0A=20=20:type=20'natnum=0A=20=20:safe=20'natnump=0A=20=20:group=20= 'bicep)=0A=0A(defvar=20bicep-ts-mode--syntax-table=0A=20=20(let=20= ((table=20(make-syntax-table)))=0A=20=20=20=20(modify-syntax-entry=20?=3D=20= =20"."=20=20=20table)=0A=20=20=20=20(modify-syntax-entry=20?\'=20"\""=20=20= table)=0A=20=20=20=20(modify-syntax-entry=20?\n=20">=20b"=20table)=0A=20=20= =20=20table)=0A=20=20"Syntax=20table=20for=20`bicep-ts-mode'.")=0A=0A= (defvar=20bicep-ts-mode--indent-rules=0A=20=20`((bicep=0A=20=20=20=20=20= ((node-is=20"}")=20parent-bol=200)=0A=20=20=20=20=20((parent-is=20= "object")=20parent-bol=20bicep-ts-mode-indent-offset)=0A=20=20=20=20=20= ((parent-is=20"for_statement")=20parent-bol=20= bicep-ts-mode-indent-offset))))=0A=0A(defvar=20bicep-ts-mode--keywords=0A= =20=20'("var"=20"param"=20"resource"=0A=20=20=20=20"module"=20"type"=20= "metadata"=0A=20=20=20=20"targetScope"=20"output"=0A=20=20=20=20"for"=20= "in")=0A=20=20"Bicep=20keywords=20for=20tree-sitter=20font-locking.")=0A=0A= (defvar=20bicep-ts-mode--font-lock-settings=0A=20=20= (treesit-font-lock-rules=0A=20=20=20:language=20'bicep=0A=20=20=20= :feature=20'comment=0A=20=20=20'((comment)=20@font-lock-comment-face)=0A=0A= =20=20=20:language=20'bicep=0A=20=20=20:feature=20'delimiter=0A=20=20=20= '(("=3D")=20@font-lock-delimiter-face)=0A=0A=20=20=20:language=20'bicep=0A= =20=20=20:feature=20'keyword=0A=20=20=20`([,@bicep-ts-mode--keywords]=20= @font-lock-keyword-face)=0A=0A=20=20=20:language=20'bicep=0A=20=20=20= :feature=20'definition=0A=20=20=20'((parameter_declaration=0A=20=20=20=20= =20=20(identifier)=20@font-lock-variable-name-face=0A=20=20=20=20=20=20= (type)=20@font-lock-type-face)=0A=20=20=20=20=20(variable_declaration=0A=20= =20=20=20=20=20(identifier)=20@font-lock-variable-name-face)=0A=20=20=20=20= =20(resource_declaration=0A=20=20=20=20=20=20(identifier)=20= @font-lock-variable-name-face)=0A=20=20=20=20=20(module_declaration=0A=20= =20=20=20=20=20(identifier)=20@font-lock-variable-name-face)=0A=20=20=20=20= =20(type_declaration=0A=20=20=20=20=20=20(identifier)=20= @font-lock-type-face)=0A=20=20=20=20=20(type_declaration=0A=20=20=20=20=20= =20(builtin_type)=20@font-lock-type-face)=0A=20=20=20=20=20= (output_declaration=0A=20=20=20=20=20=20(identifier)=20= @font-lock-variable-name-face)=0A=20=20=20=20=20(output_declaration=0A=20= =20=20=20=20=20(type)=20@font-lock-type-face))=0A=0A=20=20=20:language=20= 'bicep=0A=20=20=20:feature=20'number=0A=20=20=20'((number)=0A=20=20=20=20= =20@font-lock-number-face)=0A=0A=20=20=20:language=20'bicep=0A=20=20=20= :feature=20'string=0A=20=20=20'((string_content)=20= @font-lock-string-face)=0A=0A=20=20=20:language=20'bicep=0A=20=20=20= :feature=20'boolean=0A=20=20=20'((boolean)=20@font-lock-constant-face)=0A= =0A=20=20=20:language=20'bicep=0A=20=20=20:feature=20'functions=0A=20=20=20= '((call_expression=0A=20=20=20=20=20=20function:=20(identifier)=20= @font-lock-function-name-face))=0A=0A=20=20=20:language=20'bicep=0A=20=20= =20:feature=20'error=0A=20=20=20:override=20t=0A=20=20=20'((ERROR)=20= @font-lock-warning-face))=0A=20=20"Font-lock=20settings=20for=20BICEP.")=0A= =0A(defun=20bicep-ts-mode--defun-name=20(node)=0A=20=20"Return=20the=20= defun=20name=20of=20NODE.=0AReturn=20nil=20if=20there=20is=20no=20name=20= or=20if=20NODE=20is=20not=20a=20defun=20node."=0A=20=20= (treesit-node-text=0A=20=20=20(treesit-node-child=20node=201)=0A=20=20=20= t))=0A=0A;;;###autoload=0A(define-derived-mode=20bicep-ts-mode=20= prog-mode=20"Bicep"=0A=20=20"Major=20mode=20for=20editing=20BICEP,=20= powered=20by=20tree-sitter."=0A=20=20:group=20'bicep-mode=0A=20=20= :syntax-table=20bicep-ts-mode--syntax-table=0A=0A=20=20(when=20= (treesit-ready-p=20'bicep)=0A=20=20=20=20(treesit-parser-create=20= 'bicep)=0A=0A=20=20=20=20;;=20Comments=0A=20=20=20=20(setq-local=20= comment-start=20"#=20")=0A=20=20=20=20(setq-local=20comment-end=20"")=0A=0A= =20=20=20=20;;=20Indent.=0A=20=20=20=20(setq-local=20= treesit-simple-indent-rules=20bicep-ts-mode--indent-rules)=0A=0A=20=20=20= =20;;=20Navigation.=0A=20=20=20=20(setq-local=20= treesit-defun-type-regexp=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(rx=20(or=20"module_declaration"=20"type_declaration"=20= "variable_declaration"=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20"parameter_declaration"=20"resource_declaration"=20= "output_declaration")))=0A=20=20=20=20(setq-local=20= treesit-defun-name-function=20#'bicep-ts-mode--defun-name)=0A=0A=20=20=20= =20;;=20Font-lock.=0A=20=20=20=20(setq-local=20= treesit-font-lock-settings=20bicep-ts-mode--font-lock-settings)=0A=20=20=20= =20(setq-local=20treesit-font-lock-feature-list=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20'((comment=20delimiter=20keyword)=0A=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(definition=20number=20string=20= boolean)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (functions)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (error)))=0A=0A=20=20=20=20;;=20Imenu.=0A=20=20=20=20(setq-local=20= treesit-simple-imenu-settings=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20'(("Modules"=20"\\`module_declaration\\'"=20nil=20nil)=0A=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20("Types"=20= "\\`type_declaration\\'"=20nil=20nil)=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20("Variables"=20"\\`variable_declaration\\'"=20nil=20= nil)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ("Parameters"=20"\\`parameter_declaration\\'"=20nil=20nil)=0A=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20("Resources"=20= "\\`resource_declaration\\'"=20nil=20nil)=0A=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20("Outputs"=20"\\`output_declaration\\'"=20nil=20= nil)))=0A=0A=20=20=20=20(treesit-major-mode-setup)))=0A=0A(if=20= (treesit-ready-p=20'bicep)=0A=20=20=20=20(add-to-list=20'auto-mode-alist=20= '("\\.bicep\\'"=20.=20bicep-ts-mode)))=0A=0A(provide=20'bicep-ts-mode)=0A= =0A;;;=20bicep-ts-mode.el=20ends=20here=0A= --Apple-Mail=_63C47C86-BE22-466F-A187-E6864DEEE985 Content-Transfer-Encoding: 7bit Content-Type: text/html; charset=us-ascii
--Apple-Mail=_63C47C86-BE22-466F-A187-E6864DEEE985-- --Apple-Mail=_BE7A6854-61A3-4C97-94B7-FF602F42E545--