1"use strict";(self.webpackChunkespanso=self.webpackChunkespanso||[]).push([[231],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>u});var n=a(67294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){i(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,i=function(e,t){if(null==e)return{};var a,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)a=o[n],t.indexOf(a)>=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)a=o[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),h=p(a),u=i,k=h["".concat(s,".").concat(u)]||h[u]||m[u]||o;return a?n.createElement(k,r(r({ref:t},c),{},{components:a})):n.createElement(k,r({ref:t},c))}));function u(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=a.length,r=new Array(o);r[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p<o;p++)r[p]=a[p];return n.createElement.apply(null,r)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},11995:(e,t,a)=>{a.r(t),a.d(t,{frontMatter:()=>o,contentTitle:()=>r,metadata:()=>l,toc:()=>s,default:()=>c});var n=a(83117),i=(a(67294),a(3905));const o={sidebar_position:2,title:"Creating a Package"},r=void 0,l={unversionedId:"packages/creating-a-package",id:"packages/creating-a-package",title:"Creating a Package",description:"At some point, you might want to share your snippets with others, and the best way to do so is by creating a package!.",source:"@site/docs/packages/creating-a-package.md",sourceDirName:"packages",slug:"/packages/creating-a-package",permalink:"/docs/packages/creating-a-package",editUrl:"https://github.com/espanso/website/edit/main/docs/packages/creating-a-package.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,title:"Creating a Package"},sidebar:"tutorialSidebar",previous:{title:"External Packages",permalink:"/docs/packages/external-packages"},next:{title:"Package Specification",permalink:"/docs/packages/package-specification"}},s=[{value:"Package format, in a nutshell",id:"package-format-in-a-nutshell",children:[],level:2},{value:"Publish on the Hub (public)",id:"publish-on-the-hub-public",children:[{value:"Customizing the manifest",id:"customizing-the-manifest",children:[],level:3},{value:"Customizing the snippets",id:"customizing-the-snippets",children:[],level:3},{value:"Customizing the Readme",id:"customizing-the-readme",children:[],level:3},{value:"Publishing on the Hub",id:"publishing-on-the-hub",children:[],level:3}],level:2},{value:"Publish on a GIT repository (private or public)",id:"publish-on-a-git-repository-private-or-public",children:[{value:"Using the External repository",id:"using-the-external-repository",children:[],level:3}],level:2}],p={toc:s};function c(e){let{components:t,...a}=e;return(0,i.kt)("wrapper",(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"At some point, you might want to share your snippets with others, and the best way to do so is by ",(0,i.kt)("strong",{parentName:"p"},"creating a package!"),".\nLuckily, ",(0,i.kt)("strong",{parentName:"p"},"packages are regular match files with some metadata"),".\nSo if you already created some ",(0,i.kt)("a",{parentName:"p",href:"../../matches/basics"},"custom matches"),", then you have the necessary skills to create a custom package!"),(0,i.kt)("p",null,"In this section, we are going to discu
1ss the different ways in which you can create a package and share it with other people.\nWe'll cover how to publish it on the Espanso Hub, which is the recommended way to share a package publicly, but we are also going to discuss how to share it privately, for example with your company's team."),(0,i.kt)("div",{className:"admonition admonition-tip alert alert--success"},(0,i.kt)("div",{parentName:"div",className:"admonition-heading"},(0,i.kt)("h5",{parentName:"div"},(0,i.kt)("span",{parentName:"h5",className:"admonition-icon"},(0,i.kt)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"12",height:"16",viewBox:"0 0 12 16"},(0,i.kt)("path",{parentName:"svg",fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))),"Prerequisites")),(0,i.kt)("div",{parentName:"div",className:"admonition-content"},(0,i.kt)("p",{parentName:"div"},"This guide assumes you are comfortable working with YAML match files,\n",(0,i.kt)("inlineCode",{parentName:"p"},"git")," and Markdown.\nIf you are new to these concepts, we suggest these resources:"),(0,i.kt)("ul",{parentName:"div"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"../../matches/basics"},"Match Basics")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://docs.github.com/en/get-started/quickstart/hello-world"},"Git Basics by GitHub")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://programminghistorian.org/en/lessons/getting-started-with-markdown"},"Markdown Basics"))))),(0,i.kt)("h2",{id:"package-format-in-a-nutshell"},"Package format, in a nutshell"),(0,i.kt)("p",null,"Before diving into the different publishing opportunities,\nwe'll first need to briefly introduce the structure of a simple package.\nThe full specification can be found in the ",(0,i.kt)("a",{parentName:"p",href:"../package-specification"},"Package Specification"),"\nsection."),(0,i.kt)("p",null,"The simplest possible package is made of 3 files:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"A ",(0,i.kt)("inlineCode",{parentName:"li"},"package.yml")," file, containing the snippets you want to share."),(0,i.kt)("li",{parentName:"ul"},"A ",(0,i.kt)("inlineCode",{parentName:"li"},"_manifest.yml")," file, containing the metadata of the package.\nThis includes the package's name, author and version, among other things."),(0,i.kt)("li",{parentName:"ul"},"A ",(0,i.kt)("inlineCode",{parentName:"li"},"README.md")," file, containing a description of the package, written using the ",(0,i.kt)("a",{parentName:"li",href:"https://en.wikipedia.org/wiki/Markdown"},"Markdown")," syntax.")),(0,i.kt)("p",null,"The package can also include other files, such as a license, script, or additional match files, but they won't be covered in this example.\nIf you want to know more, please visit the ",(0,i.kt)("a",{parentName:"p",href:"../package-specification"},"Package Specification")," section."),(0,i.kt)("h2",{id:"publish-on-the-hub-public"},"Publish on the Hub (public)"),(0,i.kt)("p",null,"If you want to make the package publicly available, the\nEspanso Hub is the recommended approach.\nThe Hub itself is hosted on a ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/espanso/hub"},"GitHub repository"),", which contains all the available packages.\nLet's see how you can create your own package."),(0,i.kt)("p",null,"In this example, we are going to create a new package called ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-package"),"."),(0,i.kt)("div",{className:"admonition admonition-caution alert alert--warning"},(0,i.kt)("div",{parentName:"div",className:"admonition-heading"},(0,i.kt)("h5",{parentName:"div"},(0,i.kt)("span",{parentName:"h5",className:"admonition-icon"}
1,(0,i.kt)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 16 16"},(0,i.kt)("path",{parentName:"svg",fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))),"About package names")),(0,i.kt)("div",{parentName:"div",className:"admonition-content"},(0,i.kt)("p",{parentName:"div"},"A package name can only contain lowercase letters, numbers and the hypen symbol ",(0,i.kt)("inlineCode",{parentName:"p"},"-"),"."),(0,i.kt)("p",{parentName:"div"},"For example, the following are valid names:"),(0,i.kt)("ul",{parentName:"div"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"my-nice-package1234")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"great-package"))),(0,i.kt)("p",{parentName:"div"},"While these are NOT valid:"),(0,i.kt)("ul",{parentName:"div"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"My Package")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"my_package")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"nice@package"))))),(0,i.kt)("p",null,"Here are the first steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Visit the ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/espanso/hub"},"Hub repository")," and ",(0,i.kt)("strong",{parentName:"li"},"fork it")," on your account."),(0,i.kt)("li",{parentName:"ol"},"Clone your fork locally using ",(0,i.kt)("inlineCode",{parentName:"li"},"git"),", GitHub Desktop, or your IDE."),(0,i.kt)("li",{parentName:"ol"},"Now enter the ",(0,i.kt)("inlineCode",{parentName:"li"},"packages/")," directory and copy the contents of the ",(0,i.kt)("inlineCode",{parentName:"li"},"dummy-package")," directory in a new one, called ",(0,i.kt)("inlineCode",{parentName:"li"},"simple-package")," (this should be equal to your package name).\nAt this point, you should have the ",(0,i.kt)("inlineCode",{parentName:"li"},"packages/simple-package")," folder."),(0,i.kt)("li",{parentName:"ol"},"Then, enter the ",(0,i.kt)("inlineCode",{parentName:"li"},"packages/simple-package/0.1.0")," folder, you should find three files there:\n",(0,i.kt)("inlineCode",{parentName:"li"},"package.yml"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"_manifest.yml")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"README.md"),"."),(0,i.kt)("li",{parentName:"ol"},"You are now ready to actually customize your package, as explained below:")),(0,i.kt)("h3",{id:"customizing-the-manifest"},"Customizing the manifest"),(0,i.kt)("p",null,"Edit the ",(0,i.kt)("inlineCode",{parentName:"p"},"_manifest.yml")," file to customize the package metadata:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"name")," should be the name of your package. It must be equal to the directory name created earlier."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"title"),' is the "read-friendly" version of your package name.\nThis can contain all string characters, but it should be relatively short.'),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"description")," should contain a short description of your package."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"version")," contains the version of your package. We suggest to keep it at ",(0,i.kt)("inlineCode",{parentName:"li"},"0.1.0")," for new packages, and this number ",(0,i.kt)("em",{parentName:"li"},"must")," match that in the package path above."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"author")," contains the author name."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"tags")," contains a list of keywords."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"homepage")," your homepage or GitHub repo, for example.")),(0,i.kt)("p",null,"There are also other possible fields, please visit the ",(0,i.kt)("a",{parentName:"p",href:"../package-specification"},"Package Specification"),"\nif you are interested."),(0,i.kt)("p",null,"At this point, we should have a ",(0,i.kt)("inlineCode",{parentName:"p"},"_manifest.yml")," similar to this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="_manifest.yml"',title:'"_manifest.yml"'},'name: "simple-package"\ntitle: "Simple Package"\ndescription: A simple package to show how to create your own one!\nversion: 0.1.0\nauthor: Federico Terzi\ntags: ["sample". "words"]\nhomepage: "https://github.com/federico-terzi/espanso-hub"\n')),(0,i.kt)("h3",{id:"customizing-the-snippets"},"Customizing the snippets"),(0,i.kt)("p",null,"Once the metadata is ready, you can move to the ",(0,i.kt)("inlineCode",{parentName:"p"},"package.yml")," file.\nThat file contains the package snippets, and follow the same format used for ",(0,i.kt)("a",{parentName:"p",href:"../../matches/basics"},"regular match files"),"."),(0,i.kt)("p",null,"For example, in our
1case it could be:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="package.yml"',title:'"package.yml"'},'matches:\n - trigger: ":hello"\n replace: "Hello from the Simple Package!"\n')),(0,i.kt)("h3",{id:"customizing-the-readme"},"Customizing the Readme"),(0,i.kt)("p",null,"Finally, you should describe your package and add all the relevant documentation inside the ",(0,i.kt)("inlineCode",{parentName:"p"},"README.md")," file.\nYou should write this content using the ",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Markdown"},"Markdown")," syntax.\nThis content is what will be shown in the package's Hub page."),(0,i.kt)("p",null,"In our example, that could be something like:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-md",metastring:'title="README.md"',title:'"README.md"'},"This is a **simple package** and its purpose\nis to show how to create new Espanso packages!\n")),(0,i.kt)("h3",{id:"publishing-on-the-hub"},"Publishing on the Hub"),(0,i.kt)("p",null,"Once your package is ready, we can finally publish it on the Hub, awesome!"),(0,i.kt)("div",{className:"admonition admonition-note alert alert--secondary"},(0,i.kt)("div",{parentName:"div",className:"admonition-heading"},(0,i.kt)("h5",{parentName:"div"},(0,i.kt)("span",{parentName:"h5",className:"admonition-icon"},(0,i.kt)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},(0,i.kt)("path",{parentName:"svg",fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))),(0,i.kt)("inlineCode",{parentName:"h5"},".yml")," or ",(0,i.kt)("inlineCode",{parentName:"h5"},".yaml"),"?")),(0,i.kt)("div",{parentName:"div",className:"admonition-content"},(0,i.kt)("p",{parentName:"div"},"Whilst Espanso ",(0,i.kt)("strong",{parentName:"p"},(0,i.kt)("a",{parentName:"strong",href:"https://github.com/espanso/espanso/releases/tag/v2.3.0"},"v2.3.0")," onwards")," enables ",(0,i.kt)("inlineCode",{parentName:"p"},".yaml")," suffixed files to be loaded, please stick to ",(0,i.kt)("inlineCode",{parentName:"p"},".yml")," files in packages for now, to enable use with the previous versions."))),(0,i.kt)("p",null,"After committing your changes and pushing it to your forked version of the Hub, you'll need to ",(0,i.kt)("strong",{parentName:"p"},"open a pull request")," on the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/espanso/hub"},"espanso/hub repository"),"."),(0,i.kt)("p",null,"At that point, the Espanso team will review it and, once verified, your package will be published! Please be prepared to engage with the reviewers, who may suggest improvements, or changes to correct errors."),(0,i.kt)("h2",{id:"publish-on-a-git-repository-private-or-public"},"Publish on a GIT repository (private or public)"),(0,i.kt)("p",null,"There are times when sharing a package publicly is not possible, for example, when you plan to share it with your company's team."),(0,i.kt)("p",null,"This section quickly goes through the steps needed to set up an external Git repository to host your Espanso packages."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Firstly, ",(0,i.kt)("strong",{parentName:"li"},"fork")," the ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/espanso/espanso-external-repo-template"},"espanso-external-repo-template"),"\non your Git hosting of choice. Keep in mind that:")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"You can keep the fork private."),(0,i.kt)("li",{parentName:"ul"},"The template itself is not needed, it's just an easier way to get up to speed with the required structure.")),(0,i.kt)("ol",{start:2},(0,i.kt)("li",{parentName:"ol"},"Then, you are ready to customize the ",(0,i.kt)("inlineCode",{parentName:"li"},"example-package"),".")),(0,i.kt)("p",null,"Start by renaming the folder with the actual package name.\nIn this example, we are going to use ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-package"),"."),(0,i.kt)("p",null,"After renaming the ",(0,i.kt)("inlineCode",{parentName:"p"},"example-package")," folder to ",(0,i.kt)("inlineCode",{parentName:"p"},"simple-package"),", you can customize the included files following the instructions ",(0,i.kt)("a",{parentName:"p",href:"#customizing-the-manifest"},"above"),"."),(0,i.kt)("h3",{id:"using-the-external-repository"},"Using the External repository"),(0,i.kt)("p",null,"After committing your changes and pushing them to your repository, you are ready to use the packages!"),(0,i.kt)("p",null,"For more information about the usage, visit the ",(0,i.kt)("a",{parentName:"p",href:"../external-packages/#git-repositories-1"},"External packages")," section."))}c.isMDXComponent=!0}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.