Coder Social home page Coder Social logo

vim-fern's Introduction

🌿 vim-fern

Support Vim 8.1.2269 or above Support Neovim 0.4.4 or above Powered by vital.vim Powered by vital-Whisky MIT License Doc Doc (dev) reviewdog vim neovim

Split windows (netrw style)
nerdfont.vim / glyph-palette.vim / fern-renderer-nerdfont.vim / fern-git-status.vim

Project drawer (NERDTree style)
nerdfont.vim / glyph-palette.vim / fern-renderer-nerdfont.vim / fern-git-status.vim

See Screenshots for more screenshots.

Fern (furn) is a general purpose asynchronous tree viewer written in pure Vim script.


🔍 Click here to find fern plugins 🔍


Concept

  • Supports both Vim and Neovim without any external dependencies
  • Support split windows and project drawer explained in this article
  • Provide features as actions so that user don't have to remember mappings
  • Make operation asynchronous as much as possible to keep latency
  • User experience is more important than simplicity (maintainability)
  • Customizability is less important than simplicity (maintainability)
  • Easy to create 3rd party plugins to support any kind of trees

Installation

vim-fern has no extra dependencies so use your favorite Vim plugin manager or see How to install page for detail.

Usage

Command (Split windows)

Screencast of Split windows

Open fern on a current working directory by:

:Fern .

Or open fern on a parent directory of a current buffer by:

:Fern %:h

Or open fern on a current working directory with a current buffer focused by:

:Fern . -reveal=%

The following options are available for fern viewer.

Option Default Description
-opener edit An opener to open the buffer. See :help fern-opener for detail.
-reveal Recursively expand branches and focus the node. See :help fern-reveal for detail.
-stay Stay focus on the window where the command has called.
-wait Wait synchronously until the fern viewer become ready.
:Fern {url} [-opener={opener}] [-reveal={reveal}] [-stay] [-wait]

Command (Project drawer)

Screencast of Project drawer

All usage above open fern as split windows style. To open fern as project drawer style, use -drawer option like:

:Fern . -drawer

A fern window with project drawer style always appeared to the most left side of Vim and behaviors of some mappings/actions are slightly modified (e.g. a buffer in the next window will be used as an anchor buffer in a project drawer style to open a new buffer.)

Note that additional to the all options available for split windows style, project drawer style enables the following options:

Option Default Description
-width 30 The width of the project drawer window
-keep Disable to quit Vim when there is only one project drawer buffer
-toggle Close existing project drawer rather than focus
:Fern {url} -drawer [-opener={opener}] [-reveal={reveal}] [-stay] [-wait] [-width=30] [-keep] [-toggle]

Actions

To execute actions, hit a on a fern buffer and input an action to perform. To see all actions available, hit ? or execute help action then all available actions will be listed.

Actions

Window selector

The open:select action open a prompt to visually select window to open a node. This feature is strongly inspired by t9md/vim-choosewin.

Window selector

Renamer action (A.k.a exrename)

The rename action open a new buffer with path of selected nodes. Users can edit that buffer and :w applies the changes. This feature is strongly inspired by shougo/vimfiler.vim.

Renamer

Plugins

Users

Most of functionalities are provided as plugins in fern. So visit Github topics of fern-vim-plugin or Plugins page to find fern plugins to satisfy your wants.

For example, following features are provided as official plugins

  • Netrw hijack (Use fern as a default file explorer)
  • Nerd Fonts integration
  • Git integration (show status, touch index, ...)
  • Bookmark feature

And lot more!

Developers

Please add fern-vim-plugin topic to your fern plugin. The topic is used to list up 3rd party fern plugins.

Then please add a following badge to indicate that your plugin is for fern.

[![fern plugin](https://img.shields.io/badge/🌿%20fern-plugin-yellowgreen)](https://github.com/lambdalisue/vim-fern)

Customize

Use FileType fern autocmd to execute initialization scripts for fern buffer like:

function! s:init_fern() abort
  " Use 'select' instead of 'edit' for default 'open' action
  nmap <buffer> <Plug>(fern-action-open) <Plug>(fern-action-open:select)
endfunction

augroup fern-custom
  autocmd! *
  autocmd FileType fern call s:init_fern()
augroup END

The FileType autocmd will be invoked AFTER a fern buffer has initialized but BEFORE contents of a buffer become ready. So avoid accessing actual contents in the above function.

See Tips pages to find tips, or write pages to share your tips ;-)

Contribution

Any contribution including documentations are welcome.

Contributors who change codes should install thinca/vim-themis to run tests before complete a PR. PRs which does not pass tests won't be accepted.

License

The code in vim-fern follows MIT license texted in LICENSE. Contributors need to agree that any modifications sent in this repository follow the license.

vim-fern's People

Contributors

a5ob7r avatar brandon1024 avatar cnly avatar ealang avatar hrsh7th avatar jneidel avatar kapji avatar lambdalisue avatar lourenci avatar lumakernel avatar lunarwatcher avatar mattn avatar micchy326 avatar milly avatar mopp avatar obcat avatar prince213 avatar raa0121 avatar shanesmith avatar shatur avatar shippokun avatar skanehira avatar sourcesoft avatar supermomonga avatar tomtomjhj avatar walfie avatar wtsnjp avatar xuanduc987 avatar ydzhou avatar yuki-yano avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vim-fern's Issues

<C-w><C-p> on a opened buffer focus an invalid window with project drawer style

._______________________.
|   |                   |
|   |                   |
| A |         B         |
|   |                   |
|___|___________________|

            | vsplit {bufname}
            v

._______________________.
|   |         |         |
|   |         |         |
| A |    C    |    B    |
|   |         |         |
|___|_________|_________|
  1. User execute open:vsplit action on A
  2. Fern ask WindowLocator to focus suitable window
  3. WindowLocator move foucs from A to B
  4. Fern execute vsplit {bufname} on B
  5. C is opened at left side of B
  6. <C-w><C-p> move focus to B because it's previous

Above behavior is perfect but User feel it's unexpected because User thought the focus has moved from A to C directly (A -> B has programatically performed.)

Is there some way to open all the selected files?

Hi, thanks for the plugin. I've been finding a good alternative for the NERDTree and I think I have found it. :)

Is there some way to open all the selected nodes? I don't find anything in the readme neither in the ?.

List of possible actions with tab?

Hi, I have another suggestion to do. Sorry about that, but I'm very eager about this plugin.

In coc.nvim, when I can perform actions under some item, I can press the tab on it and a list of actions is showing in the buffer.

image

What do you think about that? This prevents the user to keep track of all the shortcuts the plugin has, besides to show him new options easily without the need to check the help or the readme.

fern.vim is extreamly slow in Windows?

Not sure if it's because of a virtual machine but it seems fern.vim works extremely slow in Windows. Try execute :Fern . with g:fern_profile = 1

note: Use https://github.com/tyru/capture.vim to capture the profile by :Capture mes after :Fern .

Vim on iTerm on macOS

Messages maintainer: Bram Moolenaar <[email protected]>
[fern] fern#internal#viewer:init enter
[fern] | fern#helper:helper.expand_node enter
[fern] | | fern#internal#node#expand enter
[fern] | | | fern#internal#node#children enter
[fern] | | | | fern#scheme#file#provider:provider_get_children enter
[fern] | | | | | fern#scheme#file#provider:children_find enter
[fern] | | | | fern#scheme#file#provider:children_find leave 0.007255 [0.007255]
[fern] | | | fern#scheme#file#provider:provider_get_children leave 0.013309 [0.013309]
[fern] | | fern#internal#node#children leave 0.018893 [0.018893]
[fern] | | fern#internal#node#expand children 0.020485 [0.020485]
[fern] | | fern#internal#node#expand sort 0.003590 [0.024075]
[fern] | | fern#internal#node#expand extend 0.003027 [0.027102]
[fern] | fern#internal#node#expand leave 0.002724 [0.029826]
[fern] | | fern#helper:helper.update_nodes enter
[fern] | | | fern#internal#core#update_nodes enter
[fern] | | | fern#internal#core#update_nodes hidden 0.003611 [0.003611]
[fern] | | | fern#internal#core#update_nodes include 0.002828 [0.006439]
[fern] | | | fern#internal#core#update_nodes exclude 0.003101 [0.009540]
[fern] | | | fern#internal#core#update_nodes let 0.002586 [0.012126]
[fern] | | | | fern#internal#core#update_marks enter
[fern] | | | | fern#internal#core#update_marks resolve 0.002008 [0.002008]
[fern] | | | | fern#internal#core#update_marks key 0.002731 [0.004739]
[fern] | | | | fern#internal#core#update_marks filter 0.002852 [0.007591]
[fern] | | | fern#internal#core#update_marks leave 0.002507 [0.010098]
[fern] | | fern#internal#core#update_nodes leave 0.014483 [0.026609]
[fern] | | | fern#helper:helper.focus_node enter
[fern] | | fern#helper:helper.focus_node leave 0.001395 [0.001395]
[fern] | fern#helper:helper.update_nodes leave 0.035127 [0.035127]
[fern] fern#helper:helper.expand_node leave 0.072152 [0.072152]
[fern] fern#internal#viewer:init expand 0.076119 [0.076119]
[fern] | fern#helper:helper.reveal_node enter
[fern] | | fern#helper:helper.update_nodes enter
[fern] | | | fern#internal#core#update_nodes enter
[fern] | | | fern#internal#core#update_nodes hidden 0.003356 [0.003356]
[fern] | | | fern#internal#core#update_nodes include 0.002741 [0.006097]
[fern] | | | fern#internal#core#update_nodes exclude 0.002875 [0.008972]
[fern] | | | fern#internal#core#update_nodes let 0.002657 [0.011629]
[fern] | | | | fern#internal#core#update_marks enter
[fern] | | | | fern#internal#core#update_marks resolve 0.002217 [0.002217]
[fern] | | | | fern#internal#core#update_marks key 0.002665 [0.004882]
[fern] | | | | fern#internal#core#update_marks filter 0.002972 [0.007854]
[fern] | | | fern#internal#core#update_marks leave 0.002664 [0.010518]
[fern] | | fern#internal#core#update_nodes leave 0.014840 [0.026469]
[fern] | | | fern#helper:helper.focus_node enter
[fern] | | fern#helper:helper.focus_node leave 0.001407 [0.001407]
[fern] | fern#helper:helper.update_nodes leave 0.035588 [0.035588]
[fern] fern#helper:helper.reveal_node leave 0.041442 [0.041442]
[fern] fern#internal#viewer:init reveal 0.045678 [0.121797]
[fern] | fern#helper:helper.redraw enter
[fern] | | fern#internal#renderer#render enter
[fern] | fern#internal#renderer#render leave 0.002899 [0.002899]
[fern] fern#helper:helper.redraw leave 0.008873 [0.008873]
[fern] fern#internal#viewer:init redraw 0.012948 [0.134745]
[fern] | fern#helper:helper.focus_node enter
[fern] fern#helper:helper.focus_node leave 0.001578 [0.001578]
[fern] fern#internal#viewer:init leave 0.005609 [0.140354]

Vim on Windows Terminal (Preview) on Windows 10 on Parallels on macOS

Messages maintainer: Bram Moolenaar <[email protected]>
[fern] fern#internal#viewer:init enter
[fern] | fern#helper:helper.expand_node enter
[fern] | | fern#internal#node#expand enter
[fern] | | | fern#internal#node#children enter
[fern] | | | | fern#scheme#file#provider:provider_get_children enter
[fern] | | | | | fern#scheme#file#provider:children_vim enter
[fern] | | | | fern#scheme#file#provider:children_vim leave 0.078515 [0.078515]
[fern] | | | fern#scheme#file#provider:provider_get_children leave 0.155541 [0.155541]
[fern] | | fern#internal#node#children leave 0.249402 [0.249402]
[fern] | | fern#internal#node#expand children 0.265435 [0.265435]
[fern] | | fern#internal#node#expand sort 0.046372 [0.311807]
[fern] | | fern#internal#node#expand extend 0.046532 [0.358339]
[fern] | fern#internal#node#expand leave 0.032064 [0.390403]
[fern] | | fern#helper:helper.update_nodes enter
[fern] | | | fern#internal#core#update_nodes enter
[fern] | | | fern#internal#core#update_nodes hidden 0.046928 [0.046928]
[fern] | | | fern#internal#core#update_nodes include 0.046305 [0.093233]
[fern] | | | fern#internal#core#update_nodes exclude 0.031577 [0.124810]
[fern] | | | fern#internal#core#update_nodes let 0.031245 [0.156055]
[fern] | | | | fern#internal#core#update_marks enter
[fern] | | | | fern#internal#core#update_marks resolve 0.016034 [0.016034]
[fern] | | | | fern#internal#core#update_marks key 0.030886 [0.046920]
[fern] | | | | fern#internal#core#update_marks filter 0.031183 [0.078103]
[fern] | | | fern#internal#core#update_marks leave 0.030701 [0.108803]
[fern] | | fern#internal#core#update_nodes leave 0.155873 [0.311928]
[fern] | | | fern#helper:helper.focus_node enter
[fern] | | fern#helper:helper.focus_node leave 0.016408 [0.016408]
[fern] | fern#helper:helper.update_nodes leave 0.421893 [0.421893]
[fern] fern#helper:helper.expand_node leave 0.922969 [0.922969]
[fern] fern#internal#viewer:init expand 0.979478 [0.979478]
[fern] | fern#helper:helper.reveal_node enter
[fern] | | fern#helper:helper.update_nodes enter
[fern] | | | fern#internal#core#update_nodes enter
[fern] | | | fern#internal#core#update_nodes hidden 0.031016 [0.031016]
[fern] | | | fern#internal#core#update_nodes include 0.031353 [0.062369]
[fern] | | | fern#internal#core#update_nodes exclude 0.031558 [0.093927]
[fern] | | | fern#internal#core#update_nodes let 0.031393 [0.125321]
[fern] | | | | fern#internal#core#update_marks enter
[fern] | | | | fern#internal#core#update_marks resolve 0.024625 [0.024625]
[fern] | | | | fern#internal#core#update_marks key 0.031241 [0.055866]
[fern] | | | | fern#internal#core#update_marks filter 0.030927 [0.086794]
[fern] | | | fern#internal#core#update_marks leave 0.046397 [0.133190]
[fern] | | fern#internal#core#update_nodes leave 0.202691 [0.328012]
[fern] | | | fern#helper:helper.focus_node enter
[fern] | | fern#helper:helper.focus_node leave 0.015900 [0.015900]
[fern] | fern#helper:helper.update_nodes leave 0.437212 [0.437212]
[fern] fern#helper:helper.reveal_node leave 0.531474 [0.531474]
[fern] fern#internal#viewer:init reveal 0.608984 [1.588462]
[fern] | fern#helper:helper.redraw enter
[fern] | | fern#internal#renderer#render enter
[fern] | fern#internal#renderer#render leave 0.030944 [0.030944]
[fern] fern#helper:helper.redraw leave 0.109894 [0.109894]
[fern] fern#internal#viewer:init redraw 0.156447 [1.744909]
[fern] | fern#helper:helper.focus_node enter
[fern] fern#helper:helper.focus_node leave 0.016074 [0.016074]
[fern] fern#internal#viewer:init leave 0.062927 [1.807837]

Fern reveal does not work

I'm at my home dir ~, editing file ~/fern/info.txt

Tried to use one of the following commands, none of them works

Fern . -reveal=%
Fern %:h -reveal=%
Fern %:p:h -reveal=%

I got this error fern: {base} ("Users/phong/fern") must be an absolute path.

I'm using vim 8.2 and latest fern.vim, please check details here: https://asciinema.org/a/9oVxreInZhp3MnsCyvD6nOsVa

Add 'terminal' action to file scheme

It's nice if file scheme support terminal action or whatever to open a terminal on a cursor node.

May I use floating window or popup for this?

Remove 'internal' from public APIs

Prior to v1.0, 1) move out from internal which should be public (used by 3rd parties), 2) move into internal APIs which should be private

Use Github actions to perform tests

Now fern.vim does not have any CI and I'd like to use Github action to perform tests but I could not be bothered to do for now...

What you need to execute is a command themis from thinca/vim-themis if you are interested in to help this issue 👍

Add a way to use custom locator

It would be nice if there is a way to use a custom locator when power users want to change the behavior of open related behaviors. For example, some people want to avoid opening a buffer on quickfix window but location-list window (a default locator avoid both.)

Create own path utility module

Internally, System.Filepath vital module is used but

  • It has more features than I needed
  • It has fewer features than I needed
  • It has non pure functions (we need to test features on Linux or Windows)
  • It does not handle C: well (#69)

So make a more suitable one for fern's file scheme.

Weird buffer behavior with open:edit

Please consider the following scenario:

:e a.file
:e b.file
:bd

The result would be a.file open.

Doing the same with :Fern -drawer:

open:edit a.file
open:edit b.file
:bd

The result: vim quits (unless any changes were done to the files).

Would be nice to have opened buffers to act like regular ones (I don't really understand how this is possible to have another type of buffer, but maybe I'm missing something here... Didn't look at the source of fern)

Edit: Apparently it only happens with -drawer. Still investigating...

The open:select action does not work on Vim

It seems open:select action does not work on Vim but Neovim.

:Fern . -drawer
select LICENSE -> a -> open:side
select README -> a -> open:side
a -> open:select

Vim

tmux 2020-03-12 03-56-57

Neovim

tmux 2020-03-12 03-59-20

Open drawer and jump to current file

Let me start by thanking you for this. I've been looking for a faster and more lightweight alternative to NERDTree for a while now and I'm very glad that I found your plugin. It seems to be able to combine everything I liked from existing file explorers out there.

Now, I’m looking for something similar to NERDTree’s NERDTreeFind command. I’d really appreciate if you could add this functionality as well. That’s one of my main usages currently with NERDTree (quickly see where a file is located within the dir hierarchy and which other files are its siblings).

It would be also great if you added some documentation as well. So far I was able to understand a lot from reading the code (e.g.: available actions, how to override mappings), but documentation definitely helps.

Some feature requests

便利なプラグインをありがとうございます。
いくつか機能要望と質問と不具合報告をさせてください。

不具合報告

  1. Fern / が正しく動作しない?
    /etc や /usr などが表示されることを期待していましたが、適切に表示できない気がします。

機能要望

  1. autoload/fern.vim あたりに利用者向けの API があると嬉しいです。
    例えば、カーソル上のノードを取得したり、現在表示中のルートパスを取得したり、cd したりなどです。(file provider 以外の場合にこまる可能性がないとも言えないので、あくまでも要望として)

質問

  1. 表示中に Fern バッファのルートパスを変更する正しい方法は Fern %path% をバッファ上で叩くで正しいでしょうか?

Is there some way to wipe out the fern buffer?

When I choose some file and in that file I press to alternate <c-^>`, the fern buffer takes place.

Is this some way to change that behavior and after I choose some file in the fern, the fern buffer wipe out itself, so I can't alternate to the previous file before I had opened the fern?

Complete command argument (:Fern)

Add complete functions for

:Fern {expr} [-drawer][-keep][-toggle][-width={width}][-reveal={reveal}]

where {expr} is % with/without modifiers, {bufname}, {dir} or {scheme}:///{path}

  • Optional arguments
  • {bufname}
  • {dir}
  • {scheme} in fern#scheme#...
  • {path} completed by {scheme} specific function
  • {reveal} completed by {scheme} specific function

hi-jacked buffers still alive

ref: https://github.com/lambdalisue/fern.vim/wiki/Tips#use-fern-as-a-default-directory-browser-hijack-netrw

My vimrc:

  function! s:hijack_directory() abort
    if !isdirectory(expand('%')) || &ft == 'fern'
      return
    endif
    Fern %
  endfunction
  function! s:plug.after.lambdalisue__fern()
    " hijack netrw
    let g:loaded_netrw             = 1
    let g:loaded_netrwPlugin       = 1
    let g:loaded_netrwSettings     = 1
    let g:loaded_netrwFileHandlers = 1
    augroup my-fern-hijack
      autocmd!
      autocmd BufEnter * ++nested call s:hijack_directory()
    augroup END
  endfunction

I tried:

:buffers!
  1 #h   "."                            line 1
  2u%a-  "fern://87b06d06/file:///Users/kyoh86$" line 1
  3u     "fern:///file:///Users/kyoh86;$" line 1
:bw
:buffers!
  1 #h   "."                            line 1
  3u%a-  "fern://cdb7d1ac/file:///Users/kyoh86$" line 1
  5u     "fern:///file:///Users/kyoh86;$" line 1

fern://... buffer is still alive.

Maybe a buffer should be wiped out (bwipeout %) before calling Fern:

  function! s:hijack_directory() abort
    let l:target=expand('%')
    if !isdirectory(l:target) || &ft == 'fern'
      return
    endif
    bwipeout %
    execute 'Fern ' . l:target
  endfunction
  function! s:plug.after.lambdalisue__fern()
    " hijack netrw
    let g:loaded_netrw             = 1
    let g:loaded_netrwPlugin       = 1
    let g:loaded_netrwSettings     = 1
    let g:loaded_netrwFileHandlers = 1
    augroup my-fern-hijack
      autocmd!
      autocmd BufEnter * ++nested call s:hijack_directory()
    augroup END
  endfunction

Change action help mapping from ? to g?

I can't perform a backward search because the plugin show the actions help. Is there some way to change that behavior?

vim-fugitive uses the g? to avoid this conflict. I think it'd be a good alternative.

Thanks.

Generic TreeDataProvider

I stumbled on this repo and seems like a really good idea. It is something I was planing to do in the future. I had even suggested something similar for vim to have vim/vim#3573 (comment)

It would be great if we have a generic plugin something like tree.vim which only cares about enabling other plugins to use the treeview. Similar to vs-code TreeDataProvider api - https://code.visualstudio.com/api/references/vscode-api#TreeDataProvider. Then can there be a plugin called tree-file.vim which only cares about file treeview. And it can be optimized for example starting a file watcher to make it more efficient. I would love to use it from vim-lsp so that we can have code tree view navigation.

I have started something very similar for a ctrlp.vim alternative - https://github.com/prabirshrestha/quickpick.vim It is at a very early stage.

I like your plug-in very much

I'm a novice at vim. I like your plug-in very much. It's lightweight, fast and powerful compared to nerdtree. But can you add exit commands, such as nerdtree, which starts the first time and exits the second time? I believe this experience will be better! I think justinmk / vim-dirvish plug-in has some good functions, such as K output file details, can you learn from it? Sorry, my English is not very good.

Fern . does not work with vim-projectionist

Hi. Thanks for the plugin.

When I open fern with the command :Fern . no files show up. It's not happening with the last tag release or with the :Fern . -drawer command. I've already removed the plugin and installed it again to keep the cache problem away.

ezgif com-video-to-gif

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.