Coder Social home page Coder Social logo

practicalli / neovim Goto Github PK

View Code? Open in Web Editor NEW
20.0 3.0 4.0 28.92 MB

Neovim, Conjure and LSP for Clojure development using Fennel configuration

Home Page: https://practical.li/neovim/

License: Creative Commons Attribution Share Alike 4.0 International

Makefile 29.72% HTML 70.28%
clojure clojure-lsp conjure neovim fennel

neovim's Introduction

Practicalli Neovim

██████╗ ██████╗  █████╗  ██████╗████████╗██╗ ██████╗ █████╗ ██╗     ██╗     ██╗
██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██║██╔════╝██╔══██╗██║     ██║     ██║
██████╔╝██████╔╝███████║██║        ██║   ██║██║     ███████║██║     ██║     ██║
██╔═══╝ ██╔══██╗██╔══██║██║        ██║   ██║██║     ██╔══██║██║     ██║     ██║
██║     ██║  ██║██║  ██║╚██████╗   ██║   ██║╚██████╗██║  ██║███████╗███████╗██║
╚═╝     ╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝   ╚═╝   ╚═╝ ╚═════╝╚═╝  ╚═╝╚══════╝╚══════╝╚═╝

Book status

GitHub issues GitHub commit activity GitHub pull requests Publish Book MegaLinter

Creative commons license

Creative Commons License This work is licensed under a Creative Commons Attribution 4.0 ShareAlike License (including images & stylesheets).

Please read the contributing section of the book before raising an issue or pull request

By submitting content ideas and corrections you are agreeing they can be used in this workshop under the Creative Commons Attribution ShareAlike 4.0 International license. Attribution will be detailed via GitHub contributors.

Sponsor Practicalli

Sponsor Practicalli via GitHub

All sponsorship funds are used to support the continued development of Practicalli series of books and videos, although most work is done at personal cost and time.

Thanks to Cognitect, Nubank and a wide range of other sponsors for your continued support

GitHub Actions

The megalinter GitHub actions will run when a pull request is created,checking basic markdown syntax.

A review of the change will be carried out by the Practicalli team and the PR merged if the change is acceptable.

The Publish Book GitHub action will run when PR's are merged into main (or the Practicalli team pushes changes to the default branch).

Publish book workflow installs Material for MkDocs version 9

Local development

Install mkdocs version 9 using the Python pip package manager

pip3 install mkdocs-material=="9.4"

Install the plugins used by the Practicalli site using Pip (these are also installed in the GitHub Action workflow)

pip3 install mkdocs-material mkdocs-callouts mkdocs-glightbox mkdocs-git-revision-date-localized-plugin mkdocs-redirects pillow cairosvg

pillow and cairosvg python packages are required for Social Cards

Fork the GitHub repository and clone that fork to your computer,

git clone https://github.com/<your-github-account>/<repository>.git

Run a local server from the root of the cloned project

make docs

The website will open at http://localhost:8000

If making smaller changes, then only rebuild the content that changes, speeding up the local development process

make docs-changed

neovim's People

Contributors

practicalli-johnny avatar rogererens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

neovim's Issues

Visual state tips

If you start selecting some text with visual mode (v), you can switch to line visual or block visual by simply pressing shift-v or ctrl-v while still in a visual mode without having to go back to the start of the selection. As long as you are in a visual mode, you can go to visual, line visual or block visual mode by pressing the appropriate key.

paste from clipboard

Neovim is a terminal app, so the terminal copy paste functions can be used

These commands can be used with / and : commands for filenames and paths

TODO: suggest other scenarios

Liniux
++ctrl++ ++shift++ ++"c"++ to copy

++ctrl++ ++shift++ ++"v"++ to paste

++ctrl++ ++shift++ ++"x"++ to cut

MacOS
++ctrl++ ++"c"++ to copy

++ctrl++ ++"v"++ to paste

++ctrl++ ++"x"++ to cut

disable neovim providers in fennel

Show how to disable a provider using Fennel configuration, in the practicalli/neovim-config-redux and in https://practical.li/neovim/install/neovim/

Neovim uses external tools for some lanaguages, e.g. node.js for Javascrip, python 3 libraries for python, etc.

During the :checkhealth the operating system is checked to ensure the requirements for each provider are enabled.

If a provider is not required it can be disabled, e.g

let g:loaded_python3_provider = 0

Add Repl workflow overview

Add a page describing the high level REPL workflow used by Practicalli, following REPL driven development

Neovim 9 new features

Summerise Neovim 9 new features

  • TUI as a remote UI
  • Lua script runner: nvim -l
  • Default colorscheme
  • Externalized UI: window layout events, ext_statusline
  • File-change detection
  • Lua remote plugin host

Keep up to date with Neovim news which tracks new developments

:help news.txt

Once a release is completed, the changes for that major version are in a news-version.txt file, e.g. news-0.9.txt

Reference

Getting Started with Fennel

Practicalli recommends Fennel as the programming language for configuring Neovim.

Important packages used in this guide are written in Fennel, especially the excellent Conjure package that provides the Clojure REPL (and support for several other language enviroments).

Fennel is a programming language that brings together the speed, simplicity, and reach of Lua with the flexibility of a lisp syntax and macro system.

  • Full Lua compatibility: Easily call any Lua function or library from Fennel and vice-versa.
  • Zero overhead: Compiled code should be just as efficient as hand-written Lua.
  • Compile-time macros: Ship compiled code with no runtime dependency on Fennel.
  • Embeddable: Fennel is a one-file library as well as an executable. Embed it in other programs to support runtime extensibility and interactive development.

Anywhere you can run Lua code, you can run Fennel code.

https://fennel-lang.org/

Fennel to Lua

Lua is the defacto language for writing Neovim packages, although there are more developers seeing Fennel as a viable alternative.

Fennel is converted to Lua using the aniseed package

Aniseed bridges the gap between Fennel (a Lisp that compiles to Lua) and Neovim. Allowing you to easily write plugins or configuration in a Clojure-like Lisp with great runtime performance.

Lua to Fennel

Package configuration is typically provided in Lua code, so requires translation into fennel.

Anti-fennel
(think antipasta) converts Lua code into Fennel code

There is an online conversion tool at See Fennel

Playing Games

Development tooling

Vim-style editing: Text objects

text-objects are used in visual or operator-pending mode.

w for instance stands for the text-object word. When you are in operator pending mode, for instance right after pressing d for delete, pressing w (so dw) will delete from the cursor position to the end of the word. Two modifiers exist to create more powerful text-objects: a (for around) and i (for inner). The former will act on the text-object on its right plus its surroundings delimiters (for a word, it’s basically the whitespaces). The latter, i, will apply the operation only inside the text-object. For a word, it means just the word, ignoring the whitespace around it.

With this, you can do really powerful editing. For instance, if you have this HTML code:

<div class="stuff">I like cookies</div>

And you want to change I like cookies to I love pasta, you can simply put your cursor anywhere in that text, and press cit, which translates to:

c = change
i = inner
t = tag

t is a text-object native to Neovim that can recognize “tags” of the filetype you are editing (here, HTML tags). So that command will change the text inside the tag. If you wanted to completely replace the whole tag with another one, you could have pressed cat, which would have removed the surroundings (i.e. the

and
).

vim commands instead of multiple cursors

Multiple cursors is a visual way to change multiple lines or matching patterns concurently.

There are many ways to achieve similar results with vim-style editing which are useful to learn

Changing a pattern in multiple places

gn textobject - e.g. gnw to select next word

change the next found occurrence with cgn, skip the next matching word with n, apply the change with . - it seems that cgn is dot-repeatable.

Neovim 0.10 will be introducing multiple cursors feature.

Purists claim there is no need for multiple cursors, as vim can do everything, but finding examples can be challenging.

Language Provider content should be reference content

The neovim install contains details of disabling language providers which may be too soon for this information, as it comes before install of the practicalli/neovim-config-redux step.

  • Separate language providers into a reference section
  • Create Neovim section under the reference setion
  • Add example code to practicalli/neovim-config-redux to disable all the language providers

[neovim] create a new file in a directory that does not exist

Neo-tree

a to add a file relative to the the currently highlighted directory in neo-tree

A to create a directory with respect to the currently highlighted directory in neo-tree

practicalli/Astronvim-config

SPC W to write the current buffer to a file, prompting for a file name (and optionally a path

Edit a file

:edit or :e and a path/filename will open a buffer with a given file. If the file does not exist, then an empty buffer will open.

:write or :w to write changes to the file, creating the file first if it did not already exist.

TAB will help traverse the directory path from the current path :lcd, showing directory completions.

The write will fail if the full directory path does not exist

Creating a new directory

Use the mkdir shell command to create a new directory, which is created relative to the current path, which can be checked with :lcd

:!mkdir full/path/to/new/directory

If a file is already opened, i.e. with :edit, there is some short-hand syntax to simplify the typing

:!mkdir -p %:h

mkdir -p - the UNIX command to create a folder, the -p option creating any parts of the path required to make the full path

% - name of the current file

:h - for the current directory (the “head” of the path).

! - the NeoVim terminal shell command

Telescope

SPC f b opens telescope file_browser, use arrow and RTN keys to navigate to the desired directory in which to create a file (or parent of the directory to be created as a child)

ESC to switch from insert to normal mode

C adds current path to the command line, adding a file name or directory path (or both) creates them

RTN to select the newly created file that now shows in the file browser view

Review neovim packages to add

Review various dotfile configurations and evaluate neovim packages to add to rafael and practicalli neovim-configs

Wanted Features

  • Magit style Git client
  • Which Key mnemonic menu

Packages to try

Current packages used

The current plugins used in rafaeldelboni/nvim-fennel-lsp-conjure-as-clojure-ide

plugin Manager

  • :wbthomason/packer.nvim {}

parsing system

  • :nvim-treesitter/nvim-treesitter {:run ":TSUpdate"
    :mod :treesitter}
  • requires node.js and node nvim package

Fennel

  • Fennel to Lua Compiler for neovim configuration and plugins - development branch
  • :Olical/aniseed {:branch :develop}

themes and visual elements

  • :projekt0n/github-nvim-theme {:mod :theme}
  • :kyazdani42/nvim-web-devicons {}

status line

  • :nvim-lualine/lualine.nvim {:mod :lualine}

Terminal

  • toggleterm

navigating a buffer
peeking at a line

file searching

  • :nvim-telescope/telescope.nvim {:requires [:nvim-telescope/telescope-ui-select.nvim
    :nvim-lua/popup.nvim
    :nvim-lua/plenary.nvim]
    :mod :telescope}

Version Control - Git

Diff current project - SPC g d - :DiffviewOpen

GitHub Issues and Pull Requests
https://github.com/pwntester/octo.nvim

  • requires GitHub CLI
❯ GITHUB_TOKEN= gh auth login
? What account do you want to log into? GitHub.com
? You're already logged into github.com. Do you want to re-authenticate? Yes
? What is your preferred protocol for Git operations? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI? Login with a web browser

! First copy your one-time code: EE9C-5A01
Press Enter to open github.com in your browser... 
✓ Authentication complete.
- gh config set -h github.com git_protocol https
✓ Configured git protocol
✓ Logged in as practicalli-john
  • :Octo pr list
  • :Octo comment add and save file to push update to GitHub

repl tools

  • :Olical/conjure {:branch :master :mod :conjure}

s-exppressions

  • :guns/vim-sexp {:mod :sexp}
  • :tpope/vim-sexp-mappings-for-regular-people {}
  • :tpope/vim-repeat {}
  • :tpope/vim-surround {}

lsp

  • :neovim/nvim-lspconfig {:mod :lspconfig}

  • snippets

  • :L3MON4D3/LuaSnip {:requires [:saadparwaiz1/cmp_luasnip]}

autocomplete

  • :hrsh7th/nvim-cmp {:requires [:hrsh7th/cmp-buffer
    :hrsh7th/cmp-nvim-lsp
    :hrsh7th/cmp-vsnip
    :PaterJason/cmp-conjure]
    :mod :cmp}

Packages from MagicKit

Package management

Menus and general usage

  • :folke/which-key.nvim {:mod :which-key} popup text menu for leader keys

  • :radenling/vim-dispatch-neovim {}

  • :tpope/vim-dispatch {}

  • :tpope/vim-eunuch {} Unix shell commands

File, Window, Buffer, Tab management

  • :nvim-telescope/telescope.nvim {:mod :telescope :requires [[:nvim-lua/popup.nvim] [:nvim-lua/plenary.nvim]]} visual lists of things with preview - files, buffers

Themes and visual elements

  • :nvim-lualine/lualine.nvim {:mod :lualine} modelone theme
  • :marko-cerovac/material.nvim {:mod :material} change background on sidebar-like windows like Nvim-Tree, Packer, terminal etc. Also includes lualine themes

Language Server Protocol

  • :neovim/nvim-lspconfig {:mod :lspconfig}

autocompletion

[ ] :hrsh7th/nvim-compe {:mod :compe} replaced by nvim-cmp

  • :hrsh7th/nvim-cmp {:mod :completion}
    completion engine plugin for neovim written in Lua

  • :tami5/compe-conjure {} compe-nvim source for conjure ?? Redundant?? Is there something for nvim-cmp ?

changes and version control

  • :mbbill/undotree {:mod :undotree}

  • :tpope/vim-fugitive {} git command line

  • :airblade/vim-gitgutter {} git only gutter indicator for added, modified, and removed lines

Vim-style editing tools

  • :tpope/vim-repeat {} comprehensive . repeat

  • :tpope/vim-surround {} surround and change surrounding parens, etc

  • :tpope/vim-commentary {} gc selected region, gcc current line, 3gcc 3 lines, gcap paragraph, gcgc

  • :tpope/vim-sleuth {} automatically work out the right sort of indenting for a file type

:ggandor/lightspeed.nvim {} advanced motions, a bit like avvy jump in Emacs and Vim motions combined - being replaced by authors new project

Lisp syntax management & s-expressions

:guns/vim-sexp {:mod :sexp} ?? precision editing of S-expressions

  • :PeterRincker/vim-argumentative {} manipulating and moving between function arguments

  • :jiangmiao/auto-pairs {:mod :auto-pairs}
    Insert or delete brackets, parens, quotes in pair

  • :tpope/vim-sexp-mappings-for-regular-people {}

Clojure specific

Random stuff

  • :tpope/vim-abolish {} substitution, coercion and abbreviations
  • :tpope/vim-unimpaired {} common ex commands, linewise mappings, toggling, enc/decoding etc.
  • :tpope/vim-vinegar {} ?? Some kind of directory traversal - cryptic description

Probably not needed with Neovim 7

  • :w0rp/ale {:mod :ale} Asynchronous Lint Engine and LSP client (replaced by treesitter ?)
  • :lewis6991/impatient.nvim {}
    Speed up loading Lua modules in Neovim to improve startup time.
  • :liuchengxu/vim-better-default {:mod :better-default} common vimscript configuration and global and local leader keys

Migrate Practicalli Neovim to MkDocs Material version 9

Update Material for MkDocs to version 9

The GitHub Publish Book workflow installs version 9 of Material for MkDocs

Install Material for MkDocs version 9 locally

pip install mkdocs-material=="9.*" 

Update mkdocs.yml configuration to include features that became optional in version 9

    - content.code.copy
    - content.action.edit
    - content.action.view
    - navigation.footer

Reference

neo-tree: open files with system viewer

shift + enter on a file in neo-tree will open the file using the associated system viewer.

e.g. a .png file will open in the operating system image viewer

Start Practicalli Neovim book

Creating the neovim book

Neovim for Clojure development using fennel, clojure-lsp (neovim-lsp client - neovim7 required) and conjure, with Clojure CLI

Good starting configuration:

Practicalli modifications

Add features commonly used in Spacemacs to Neovim setup

Resources

A more involved Neovim configuration

Desired features

Related #128

Structural editing in Neovim

tpope/vim-sexp-mappings-for-regular-people

<e and >e moving elements around

Is there a way to move hash-map key value pairs together?

hack - move each element of pair one at a time
does not work if you try to move on the edge of the

  nmap >p 3>e3B3>e
  nmap <p 2<e4E2<e

sexp supports moving around visually selected pairs. I've created a PR for missing mapping tpope/vim-sexp-mappings-for-regular-people#12 . If you have the mapping from the PR than swapping pairs is

nmap >p vaeE>eo<Esc>
nmap <p vaeE<eo<Esc>

selects around current element, moves to the next, visually swaps, moves cursor to the beginning of selection and exists visual mode. this way it works on the edges of a form

I don't seem to have such visual mode mappings by default, but this seems to do the trick

vmap <e <Plug>(sexp_swap_element_backward)
vmap >e <Plug>(sexp_swap_element_forward)

Neovim registers

:help registers

Neovim has the concept of registers (:h registers).

Many registers have a semantic use, like the unnamed register (""), that is used by default by all the d, c, s, x and p commands.

read the help pages for all the registers

  • " to select a register, e.g. "a is the a register.

C-r in insert mode pastes the content of any register, e.g. C-r a to paste the content of "a

Registers can be used while writing macros.

Clojure test runner in Neovim and Conjure

Run unit tests from within Neovim, showing a summary of test results or a full test report (especially if there are failures)

Links in test report to jump to tests / code that is cause of error

Clojure Test runners

  • Conjure ?
  • Cognitech Labs
  • Kaocha test runner

Run tests in Neovim

Does Conjure support this?

Are tools like neotest - no support for Clojure currently

Any other useful packages

External test runner

In a buffer or separate terminal session, start a test runner in watch mode. Tests run automatically when the code changes are saved

clojure -X:test/watch

Start the watcher with focused or skiped tests by name or meta data (test selectors)
https://cljdoc.org/d/lambdaisland/kaocha/1.66.1034/doc/6-focusing-and-skipping

For example, specify test selectors to run a sub-set of tests based on selector meta data added to deftest code

clojure -X:test/watch :skip-meta :persistence 

TODO: check syntax of Kaocha test selectors

Using Kaocha, specific test namespaces (or specific tests) can be run (or excluded)

clojure -X:test/watch :namespace '[practicalli.server"]

TODO: check syntax of Kaocha namespace and specific tests

Reference

  • neotest - Neovim test plugin with some language support (not Clojure - but maybe could be added)

Neovim - toggle between src and test files

tpope/projectionist
https://github.com/tpope/vim-projectionist

Suggested binding: SPC p a for project alternate

Swap between src and test with a simple binding
Per project configuration config using projections.json file in root of project

{
  "src/*.clj": {
    "alternate": "test/{}_test.clj",
    "type": "source"
  },
  "test/*_test.clj": {
    "alternate": "src/{}.clj",
    "type": "test"
  }
}

Global configuration
set it globally if a directory contains a file, using g:projectionist_heuristics

create a file $HOME/.vim/syntax/clojure.vim containing

"
" Projections
"
autocmd User ProjectionistDetect
  \ call projectionist#append(getcwd(),
  \ {
  \   'src/*.clj': {
  \     'alternate': 'test/{}_test.clj',
  \     'type': 'source'
  \   },
  \   'test/*_test.clj': {
  \     'alternate': 'src/{}.clj',
  \     'type': 'test'
  \   },
  \ })

Evaluate AstroNvim as a suitable base configuration

Use AstroNvim for several weeks and evaluate its suitability for a Clojure development environment

  • Conjure support
  • Structured editing support
    • paredit
    • nvim-parinfer
  • Clojure LSP support (Mason)
  • Mnemonic key bindings (or easy customisation)
    • which-key user configuration (from astronvim user config example)
  • Git Client (magit style preferably)
    • neogit (fully featured magit - but no forge - see octo) (AstroNvim Community package)
    • lazygit (quick and simple) (AstroNvim)
    • Octo client for GitHub (AstroNvim Community package)
  • Snippets
  • Easy to configure
  • Separate user configuration
  • Supports Neovim 9
  • Add configuration to Practicalli Neovim
  • Icon Font support i.e. NerdFont (version 3 onward)

Substitution in neovim

Neovim built-in substitution command

:%s command substitutes text in the current buffer, e.g substitute the word have by had

:%s/have/had/g`

The g modifier replaced all occurrences on the same line, omitting g only replaces the first occurrence on each line.

c modifier prompts for confirmation of each replace occurrence.

Use visual select to replace all of the 32 arguments to functions by 100 without replacing 32 in the declarations

let _ = 32;
let _ = 32;
let _ = 32;

let x = foo(32);
let y = bar(32);
let z = zoo(32);
let a = quux(32);
let b = tronfibulate(32);

Select all the lines starting from let x = … to let b = … and press :

enter the substitute command to scope it to that selection;

% means the whole file

:'<,'>, are visual marks.

Using visual select the substitute command

:'<,'>s/32/100/g

the replacement was limited to the portion of text selected. That works in visual, line and block visual modes

:help s_flags for more information about the substitute flags.

Evaluate mkdocs for books

Evaluate mkdocs as an alternative to GitBook

Test out on Practicalli Neovim book as it is much smaller than other books, in case there is some conversion to do.

neovim insert filename or path into buffer

How to get the filename or full path of a file and then past it into a buffer

Use cases

  • mkdocs navigation

Normal mode

" % is the neovim register that holds the filename associated with the current buffer (if it has a file associated with it)

" % p will past the filename into the buffer in normal mode

Vim command

:read inserts the output of a command into the current buffer

:read echo % inserts the filename

:read! echo %:p inserts the full path of the file

:help read and :help filename-modifiers for more details

:put % inserts the filename from the % register

:put=expand('%:p') inserts the full path to the file

A more terse approach is to use !! which replaces the current line in the buffer with the result of the next command

!!echo %

Use basename to ensure only the the file name even when the register contains the full path

`!!basename %``

Bind a key (review)

inserts the current filename without the extension at the cursor position, when you are in insert mode.

:inoremap \fn =expand("%:t:r")
To keep the extension use:

:inoremap \fn =expand("%:t")
To insert the absolute path of the directory the file is in use:

:inoremap \fn =expand("%:p:h")
To insert the relative path of the directory the file is in use:

:inoremap \fn =expand("%:h")

[install] example of disabling a plugin

Include example configuration that shows how to disable plugins provided by Practicalli Astro and Astro Community

Example: disable nvim-parinfer and nvim-treesitter-sexp plugins which are included in the Astro Community Clojure pack

  -- ----------------------------------------------
  -- Packs
  -- Treesitter: clojure , Lsp: clojure-lsp, Lint/format:
  { import = "astrocommunity.pack.clojure" },
  { "nvim-parinfer", enabled = false },
  { "nvim-treesitter-sexp", enabled = false },
  -- ----------------------------------------------

Disabled plugins are shown in the Lazy plugin manager status popup, SPC p s

image

install: fonts and nerdfonts

Include more information on how to install Fonts, especially Nerd fonts.

This information may be specific to the terminal app used. Use terminal specific content in Practicalli Engineering Playbook.

Kitty seems to prefer fonts added into .local/share/fonts/ directory (although this could be my kitty config)

Spacemacs inspired keybindings

SPC p t - toggle NERDTreeToggle

SPC w hjkl - navigate splits (vim equivalent of windows)
? How can splits be moved around?

feat(termux): GitHub ssh enhancements

Adding a local SSH public key to GitHub account

 termux-clipboard-set < $HOME/.ssh/id_rsa.pub && xdg-open https://github.com/settings/keys

Cache the SSH key
Termux doesn't run ssh-agent but does support
SSH key caching using the ssha command

This command seems to cache for ssh connection but not for git command.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.