repos / neovimcraft

website that makes it easy to find neovim plugins
git clone https://github.com/neurosnap/neovimcraft.git

commit
390cc0f
parent
65b2bd8
author
Eric Bower
date
2021-07-22 21:14:25 +0000 UTC
Nav (#1)

11 files changed,  +476, -52
A .nvmrc
A .nvmrc
+1, -0
1@@ -0,0 +1 @@
2+12.21.0
A src/lib/nav.svelte
+162, -0
  1@@ -0,0 +1,162 @@
  2+<script lang="ts">
  3+  import Icon from '$lib/icon.svelte';
  4+  import { page } from '$app/stores';
  5+  let path = '';
  6+  page.subscribe((store) => {
  7+    path = store.path;
  8+  });
  9+  const links = [
 10+    ['/', 'plugins'],
 11+    ['/guides', 'guides'],
 12+    ['/about', 'about'],
 13+  ];
 14+  let isOpen = false;
 15+  const open = () => {
 16+    isOpen = true;
 17+  };
 18+  const close = () => {
 19+    isOpen = false;
 20+  };
 21+</script>
 22+
 23+<div class="nav">
 24+  <h1 id="logo">
 25+    neovim craft
 26+    <a href="https://github.com/neurosnap/neovimcraft" target="_blank">
 27+      <Icon icon="github" />
 28+    </a>
 29+  </h1>
 30+  <div class="links">
 31+    {#each links as link}
 32+      <a href={link[0]} class="link" class:active={path === link[0]}>{link[1]}</a>
 33+    {/each}
 34+  </div>
 35+  <div class="menu-btn" on:click={open}><img src="/menu.svg" alt="menu" /></div>
 36+  {#if isOpen}
 37+    <div class="menu-container">
 38+      <div class="menu-overlay" on:click={close} />
 39+      <div class="menu">
 40+        <div class="menu-header">
 41+          <h1>neovim craft</h1>
 42+          <div class="menu-btn" on:click={close}><img src="/menu.svg" alt="menu" /></div>
 43+        </div>
 44+        <div class="menu-body">
 45+          {#each links as link}
 46+            <a href={link[0]} class="link" class:active={path === link[0]}>{link[1]}</a>
 47+          {/each}
 48+        </div>
 49+      </div>
 50+    </div>
 51+  {/if}
 52+</div>
 53+
 54+<style>
 55+  .nav {
 56+    display: flex;
 57+    justify-content: space-between;
 58+    align-items: center;
 59+    padding: 0 10px;
 60+    margin-bottom: 15px;
 61+  }
 62+
 63+  .links {
 64+    display: flex;
 65+    justify-content: space-between;
 66+    width: 250px;
 67+  }
 68+
 69+  .link {
 70+    font-size: 20px;
 71+    text-decoration: none;
 72+    color: var(--text-color);
 73+  }
 74+
 75+  .link:hover {
 76+    color: var(--highlight-color);
 77+    text-decoration: underline;
 78+  }
 79+
 80+  .menu-overlay {
 81+    position: fixed;
 82+    top: 0;
 83+    left: 0;
 84+    width: 100vw;
 85+    height: 100vh;
 86+    background-color: rgba(0, 0, 0, 0.6);
 87+    z-index: 1;
 88+  }
 89+
 90+  .menu-container {
 91+    display: none;
 92+  }
 93+
 94+  .menu {
 95+    position: fixed;
 96+    top: 0;
 97+    right: 0;
 98+    width: 80vw;
 99+    height: 100vh;
100+    flex-direction: column;
101+    align-items: end;
102+    background-color: var(--bg-color);
103+    z-index: 1;
104+    padding: 0 15px;
105+    padding-top: 0;
106+    border-left: 1px solid var(--primary-color);
107+  }
108+
109+  .menu-header {
110+    display: flex;
111+    justify-content: space-between;
112+    align-items: center;
113+  }
114+
115+  .menu-body {
116+    display: flex;
117+    flex-direction: column;
118+  }
119+
120+  .menu-body a {
121+    margin: 10px 0;
122+  }
123+
124+  .menu-btn {
125+    display: none;
126+    cursor: pointer;
127+    width: 24px;
128+    height: 24px;
129+  }
130+
131+  #logo {
132+    display: flex;
133+    align-items: center;
134+  }
135+
136+  #logo > a {
137+    margin-left: 15px;
138+  }
139+
140+  @media only screen and (max-width: 700px) {
141+    .nav {
142+      padding: 0 15px;
143+    }
144+
145+    .links {
146+      display: none;
147+    }
148+
149+    .link {
150+      margin: 10px 0;
151+    }
152+
153+    .menu-btn {
154+      display: block;
155+    }
156+
157+    .menu-container {
158+      display: flex;
159+      justify-content: center;
160+      align-items: center;
161+    }
162+  }
163+</style>
A src/routes/about.svelte
+94, -0
 1@@ -0,0 +1,94 @@
 2+<script lang="ts">
 3+  import Nav from '$lib/nav.svelte';
 4+</script>
 5+
 6+<Nav />
 7+
 8+<div class="container">
 9+  <div class="view">
10+    <div class="intro">
11+      <div class="blurb">
12+        <h1>Hey all!</h1>
13+        <p>
14+          My name is <strong>Eric Bower</strong> and I built this site because neovim is awesome and
15+          I want to provide resources for searching an building neovim plugins.
16+        </p>
17+      </div>
18+      <img class="profile" src="/me.jpg" alt="Eric Bower" />
19+    </div>
20+    <div>
21+      <p>
22+        I&apos;m a professional software engineer who has been programming since I was 13 years old.
23+        I love building software as much as I love building something that people find useful. Most
24+        of my time is devoted to growing my ability to build products.
25+      </p>
26+      <p>
27+        I also care deeply about open-source code and have an active{' '}
28+        <a href="https://github.com/neurosnap" target="_blank">Github</a>
29+        , check it out if you&apos;re interested. I also write{' '}
30+        <a href="https://erock.io" target="_blank">blog articles about software</a>.
31+      </p>
32+      <p>
33+        I&apos;m happy to read feedback about neovim craft so please feel free to{' '}
34+        <a href="mailto:eric@neovimcraft.com" target="_blank">email me</a>.
35+      </p>
36+    </div>
37+    <div>
38+      <h2>FAQ</h2>
39+      <p>Do you have questions not answered here? Email me!</p>
40+      <h3>Where do we get our content from?</h3>
41+      <p>
42+        As of right now, most of our data is scraped from github. You can find our scrape script
43+        <a href="https://github.com/neurosnap/neovimcraft/blob/main/src/scrape.ts" target="_blank"
44+          >here</a
45+        >.
46+      </p>
47+      <h3>How can I submit a plugin or resource to this project?</h3>
48+      <p>
49+        The easiest way is to submit a PR that adds the resource to our
50+        <a
51+          href="https://github.com/neurosnap/neovimcraft/blob/main/src/lib/resources.json"
52+          target="_blank">resources.json file</a
53+        >.
54+      </p>
55+    </div>
56+  </div>
57+</div>
58+
59+<style>
60+  :global(body) {
61+    overflow-y: auto;
62+  }
63+
64+  .container {
65+    display: flex;
66+    justify-content: center;
67+  }
68+
69+  .view {
70+    width: 600px;
71+  }
72+
73+  .intro {
74+    display: flex;
75+    align-items: center;
76+    justify-content: center;
77+    margin-bottom: 8px;
78+  }
79+
80+  .blurb {
81+    margin-right: 8px;
82+  }
83+
84+  .profile {
85+    border-radius: 9999px;
86+    width: 200px;
87+    height: 200px;
88+  }
89+
90+  @media only screen and (max-width: 700px) {
91+    .container {
92+      padding: 0 15px;
93+    }
94+  }
95+</style>
A src/routes/guides.svelte
+177, -0
  1@@ -0,0 +1,177 @@
  2+<script lang="ts">
  3+  import Nav from '$lib/nav.svelte';
  4+  import Tag from '$lib/tag.svelte';
  5+
  6+  interface Article {
  7+    text: string;
  8+    desc: string;
  9+    url: string;
 10+    media: string;
 11+    date: Date;
 12+    tags: string[];
 13+  }
 14+
 15+  const zero = (num: number) => (num < 10 ? `0${num}` : `${num}`);
 16+  const format = (date: Date) => {
 17+    return `${date.getFullYear()}-${zero(date.getMonth())}-${zero(date.getDate())}`;
 18+  };
 19+
 20+  const createArticle = (article: Partial<Article> = {}): Article => {
 21+    return {
 22+      text: '',
 23+      desc: '',
 24+      url: '',
 25+      media: '',
 26+      tags: [],
 27+      date: new Date(),
 28+      ...article,
 29+    };
 30+  };
 31+
 32+  const links = [
 33+    createArticle({
 34+      text: 'nvim lua guide',
 35+      url: 'https://github.com/nanotee/nvim-lua-guide',
 36+      desc: 'A guide to using Lua in Neovim',
 37+      tags: ['meta'],
 38+      media:
 39+        'https://opengraph.githubassets.com/bf01b0af4a6d4814fae6c35808e0d542bee8ce8b4449d2b64f2b40f4efc81562/nanotee/nvim-lua-guide',
 40+    }),
 41+    createArticle({
 42+      text: 'What is the benefit of writing plugins in lua?',
 43+      url:
 44+        'https://www.reddit.com/r/neovim/comments/mg5ip7/what_is_the_benefit_of_writing_plugins_in_lua',
 45+      desc:
 46+        "I hear that Lua is a first-class language for neovim but I'm not really sure what that means. Can someone explain what neovim-specific benefits there are to writing your plugin in Lua?",
 47+      date: new Date('2021-03-21'),
 48+      tags: ['plugins'],
 49+    }),
 50+    createArticle({
 51+      text: 'How to write neovim plugins in lua',
 52+      url: 'https://www.2n.pl/blog/how-to-write-neovim-plugins-in-lua',
 53+      media: 'https://www.2n.pl/system/blog_posts/photos/000/000/019/original/whid.png?1617885408',
 54+      date: new Date('2021-05-02'),
 55+      tags: ['plugins'],
 56+      desc:
 57+        "One of goals which neovim devs set for themselves, was making lua the first-class scripting language alternative to viml. Since version 0.4 its' interpreter along with 'stdlib' have been already built into the editor.",
 58+    }),
 59+    createArticle({
 60+      text: 'From init.vim to init.lua',
 61+      url: 'https://teukka.tech/luanvim.html',
 62+      tags: ['config'],
 63+      desc:
 64+        'I want to illustrate the process of learning how to take advantage of the powerful scripting capabilities that are available in the Neovim runtime.',
 65+      date: new Date('2021-07-22'),
 66+    }),
 67+    createArticle({
 68+      text: 'How to make UI for neovim plugins in Lua',
 69+      url: 'https://dev.to/2nit/how-to-make-ui-for-neovim-plugins-in-lua-3b6e',
 70+      tags: ['plugins'],
 71+      desc:
 72+        "Let's create a simple plugin that will show us last opened files in handy side navigation.",
 73+      media:
 74+        'https://res.cloudinary.com/practicaldev/image/fetch/s--AqStf1TN--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/i/p1vusfl4dhivlv7hb559.png',
 75+    }),
 76+    createArticle({
 77+      text: 'Neovim 0.5 features and the switch to init.lua',
 78+      url: 'https://oroques.dev/notes/neovim-init',
 79+      tags: ['config'],
 80+      desc:
 81+        'This post will help you write a very basic init.lua which include all these new features.',
 82+      media: 'https://raw.githubusercontent.com/ojroques/nvim-lspfuzzy/main/demo.gif',
 83+      date: new Date('2021-07-18'),
 84+    }),
 85+    createArticle({
 86+      text: 'Learn Lua in Y minutes',
 87+      url: 'https://learnxinyminutes.com/docs/lua/',
 88+      tags: ['learn'],
 89+      desc: 'A brief introduction into the lua programming language',
 90+      date: new Date('2021-07-22'),
 91+    }),
 92+    createArticle({
 93+      text: 'Learn lua quick guide',
 94+      tags: ['learn'],
 95+      url: 'https://github.com/medwatt/Notes/blob/main/Lua/Lua_Quick_Guide.ipynb',
 96+      media:
 97+        'https://opengraph.githubassets.com/6c6bc0166cc8b9679b671ca24b9a16329977677ef1130f81d939a14e22fc9a9e/medwatt/Notes',
 98+      desc: 'This guide is also a good resource for getting started quickly',
 99+      date: new Date('2021-07-22'),
100+    }),
101+    createArticle({
102+      text: 'Lua interactive tutorial',
103+      tags: ['learn'],
104+      url: 'https://www.luascript.dev/learn',
105+      desc: 'New to lua?  Start with us and learn!',
106+      date: new Date('2021-07-22'),
107+      media: '/lua-script.png',
108+    }),
109+  ].sort((a, b) => b.date.getTime() - a.date.getTime());
110+</script>
111+
112+<Nav />
113+
114+<div class="container">
115+  <div class="view">
116+    <h1>guides</h1>
117+    <p>
118+      I've been compiling a list of guides that help people build and use lua plugins for neovim.
119+    </p>
120+    {#each links as link}
121+      <div class="article">
122+        {#if link.media}
123+          <a href={link.url} target="_blank">
124+            <img src={link.media} alt={link.text} class="media" />
125+          </a>
126+        {/if}
127+        <div class="article-header">
128+          <h2>
129+            <a href={link.url} target="_blank">{link.text}</a>
130+          </h2>
131+          <small class="date">{format(link.date)}</small>
132+          <div class="tags">
133+            {#each link.tags as tag}
134+              <Tag tag={{ id: tag, count: 1 }} showCount={false} />
135+            {/each}
136+          </div>
137+        </div>
138+        {#if link.desc}{link.desc}{/if}
139+      </div>
140+    {/each}
141+  </div>
142+</div>
143+
144+<style>
145+  :global(body) {
146+    overflow-y: auto;
147+  }
148+
149+  .container {
150+    padding: 0 15px;
151+    display: flex;
152+    justify-content: center;
153+  }
154+
155+  .view {
156+    width: 600px;
157+  }
158+
159+  .article-header {
160+    display: flex;
161+    flex-direction: column;
162+    margin-bottom: 10px;
163+  }
164+
165+  .article {
166+    display: flex;
167+    flex-direction: column;
168+    margin: 15px 0;
169+    padding: 15px;
170+    border: 1px solid var(--primary-color);
171+  }
172+
173+  .media {
174+    width: 100%;
175+    max-width: 580px;
176+    height: auto;
177+  }
178+</style>
M src/routes/index.svelte
+14, -32
  1@@ -1,6 +1,4 @@
  2 <script context="module" lang="ts">
  3-  export const prerender = true;
  4-
  5   import { derivePluginData } from '$lib/plugin-data';
  6   import * as db from '$lib/db.json';
  7 
  8@@ -26,6 +24,7 @@
  9   import TagItem from '$lib/tag.svelte';
 10   import Icon from '$lib/icon.svelte';
 11   import PluginItem from '$lib/plugin.svelte';
 12+  import Nav from '$lib/nav.svelte';
 13 
 14   let timer: NodeJS.Timeout;
 15   const debounce = (fn: (v: string) => any) => {
 16@@ -92,16 +91,9 @@
 17   $: filterTotal = filterPlugins({ search, plugins });
 18 </script>
 19 
 20-<div class="container">
 21-  <div class="intro">
 22-    <h1 id="logo">
 23-      neovim craft
 24-      <a href="https://github.com/neurosnap/neovimcraft" target="_blank">
 25-        <Icon icon="github" />
 26-      </a>
 27-    </h1>
 28-  </div>
 29+<Nav />
 30 
 31+<div class="container">
 32   <div class="search_view">
 33     <span class="search_icon"><Icon icon="search" /></span>
 34     <input
 35@@ -116,9 +108,9 @@
 36       </span>
 37     {/if}
 38   </div>
 39+  <div class="desc">Search through our curated list of neovim plugins</div>
 40 
 41   <div class="sidebar">
 42-    <div class="desc">Search through our curated list of neovim plugins</div>
 43     {#each tags as tag}
 44       <TagItem {tag} {onSearch} />
 45     {/each}
 46@@ -134,7 +126,7 @@
 47 </div>
 48 
 49 <svelte:head>
 50-  <title>Neovim Awesome - Plugin Search</title>
 51+  <title>neovim craft - plugin search</title>
 52 </svelte:head>
 53 
 54 <style>
 55@@ -144,6 +136,11 @@
 56 
 57   .desc {
 58     margin-bottom: 5px;
 59+    margin-left: 10px;
 60+    grid-row: 1;
 61+    grid-column: 1;
 62+    align-items: center;
 63+    display: flex;
 64   }
 65 
 66   .search_view {
 67@@ -179,42 +176,28 @@
 68   }
 69 
 70   .container {
 71-    height: 100vh;
 72     display: grid;
 73+    height: calc(100vh - 50px);
 74     grid-template-columns: minmax(250px, 400px) minmax(350px, 600px);
 75     grid-template-rows: 50px 1fr;
 76     column-gap: 10px;
 77   }
 78 
 79-  .intro {
 80-    padding: 0 10px 0 10px;
 81-    grid-column: 1;
 82-    grid-row: 1;
 83-  }
 84-
 85-  #logo {
 86-    display: flex;
 87-    align-items: center;
 88-  }
 89-
 90-  #logo > a {
 91-    margin-left: 15px;
 92-  }
 93-
 94   .sidebar {
 95     grid-column: 1;
 96     grid-row: 2;
 97     padding: 0 10px;
 98-    height: calc(100vh - 50px);
 99+    overflow-y: auto;
100+    padding-bottom: 25px;
101   }
102 
103   .plugins {
104     grid-column: 2;
105     grid-row: 2;
106+    overflow-y: auto;
107   }
108 
109   .plugins_list {
110-    height: calc(100vh - 50px);
111     width: 100%;
112     overflow-y: auto;
113     overflow-x: hidden;
114@@ -226,7 +209,6 @@
115       justify-content: center;
116     }
117 
118-    .intro,
119     .sidebar {
120       display: none;
121     }
M src/routes/plugin/[username]/[repo].svelte
+4, -1
 1@@ -25,6 +25,7 @@
 2   import type { Plugin, Tag } from '$lib/types';
 3   import PluginView from '$lib/plugin-view.svelte';
 4   import Icon from '$lib/icon.svelte';
 5+  import Nav from '$lib/nav.svelte';
 6 
 7   export let plugin: Plugin;
 8   export let tags: Tag[];
 9@@ -45,6 +46,8 @@
10   <meta name="twitter:description" content="{plugin.id}: {plugin.description}" />
11 </svelte:head>
12 
13+<Nav />
14+
15 <div class="container">
16   <div class="view">
17     <div class="header">
18@@ -58,7 +61,7 @@
19 
20 <style>
21   :global(body) {
22-    overflow-y: scroll;
23+    overflow-y: auto;
24   }
25 
26   .container {
A static/lua-script.png
+0, -0
M static/main.css
+22, -18
 1@@ -92,21 +92,25 @@ input:focus {
 2 }
 3 
 4 button {
 5-    padding: 10px 15px;
 6-    margin: 0 10px;
 7-    background-color: var(--highlight-color);
 8-    color: var(--primary-color);
 9-    cursor: pointer;
10-    outline: 0;
11-    border: 1px solid var(--primary-color);
12-    border-radius: 3px;
13-  }
14-
15-  button:disabled {
16-    cursor: default;
17-    background-color: var(--primary-color);
18-  }
19-
20-  button:hover:enabled {
21-    background-color: var(--highlight-secondary);
22-  }
23+  padding: 10px 15px;
24+  margin: 0 10px;
25+  background-color: var(--highlight-color);
26+  color: var(--primary-color);
27+  cursor: pointer;
28+  outline: 0;
29+  border: 1px solid var(--primary-color);
30+  border-radius: 3px;
31+}
32+
33+button:disabled {
34+  cursor: default;
35+  background-color: var(--primary-color);
36+}
37+
38+button:hover:enabled {
39+  background-color: var(--highlight-secondary);
40+}
41+
42+.active {
43+  color: var(--pink) !important;
44+}
A static/me.jpg
+0, -0
A static/menu.svg
+1, -0
1@@ -0,0 +1 @@
2+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f2f2f2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
M svelte.config.js
+1, -1
1@@ -14,7 +14,7 @@ const config = {
2       // default options are shown
3       pages: 'build',
4       assets: 'build',
5-      fallback: '404.html',
6+      fallback: null,
7     }),
8     prerender: {
9       force: true,