├── License.md ├── README.md ├── doc └── quicklink.txt ├── ftplugin └── markdown │ └── quicklink.vim └── overview.gif /License.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Chris Toomey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Vim Quicklink 2 | ============= 3 | 4 | A Vim plugin for quickly looking up a topic and inserting the relevant link 5 | into a markdown document. 6 | 7 | ![Overview](./overview.gif) 8 | 9 | Usage 10 | ----- 11 | 12 | ### URL Searching 13 | 14 | The main feature of `vim-quicklink` is to search for and insert a relevant link 15 | without needing to leave vim. You can do this by visually selecting the word or 16 | phrase you want to add a link around, then press `` to activate the plugin. 17 | A prompt will pop up asking for the text to search for, defaulting to the 18 | highlighted text. Hit `` to run the search. A results window will pop up 19 | with the following keymaps: 20 | 21 | - `` - Jump to next search result; 22 | - `` - Jump to the previous result; 23 | - `o` - open the link for the result under the cursor in your browser; 24 | - `` - accept the result under the cursor; 25 | - `q` - quit out of the quicklink adventure. 26 | 27 | ### Link Opening 28 | 29 | `vim-quicklink` also updates the `gx` mapping from `netrw` to work with markdown 30 | link format. The default behavior of `gx` when your cursor is over a URL will 31 | still work and is unchanged, but you can now also use `gx` on a markdown link 32 | such as `[webapi-vim][]` in this readme and `vim-quicklink` will find and open 33 | the associated URL using `netrw`. All keymaps : 34 | 35 | - `gx` - Open link under cursor; 36 | - `gl` - Go to link defintion under cursor. 37 | 38 | Installation 39 | ------------ 40 | 41 | This plugin relies on a [webapi-vim][], a vimscript wrapper for interacting 42 | with APIs. Assuming you're using Vundle, add the following line to your 43 | `~/.vimrc` file: 44 | 45 | ``` vim 46 | Bundle 'mattn/webapi-vim' 47 | Bundle 'christoomey/vim-quicklink' 48 | ``` 49 | 50 | [webapi-vim]: https://github.com/mattn/webapi-vim 51 | -------------------------------------------------------------------------------- /doc/quicklink.txt: -------------------------------------------------------------------------------- 1 | *quicklink.txt* For Vim version 7.3 Last change: February 18th, 2015 2 | 3 | *quicklink* 4 | 5 | INTRODUCTION *quicklink-introduction* 6 | 7 | A Vim plugin for quickly looking up a topic and inserting the relevant link 8 | into a markdown document. 9 | 10 | ============================================================================== 11 | MAPPINGS *quicklink-mappings* 12 | 13 | When in 'visual' mode searches for the selected 14 | expression and opens an interactive window in which 15 | the first four search results of the expression have 16 | been listed. 17 | 18 | gx Open a markdown formated link under the cursor. 19 | "NOTE": The default behavior of `gx` when your cursor 20 | is over a URL will still work and is unchanged. 21 | 22 | gl Go to link defintion under cursor. 23 | 24 | Interactive window~ 25 | 26 | Jump to next search result. 27 | 28 | Jump to the previous result. 29 | 30 | o Open the link for the result under the cursor in your 31 | browser. 32 | 33 | Accept the result under the cursor. 34 | 35 | q Quit out of the quicklink adventure. 36 | 37 | ============================================================================== 38 | ABOUT *quicklink-about* 39 | 40 | Get the latest version of |quicklink| on GitHub: 41 | 42 | https://github.com/christoomey/vim-quicklink 43 | 44 | vim:tw=78:ts=8:ft=help:norl: 45 | -------------------------------------------------------------------------------- /ftplugin/markdown/quicklink.vim: -------------------------------------------------------------------------------- 1 | " File: quicklink.vim 2 | " Author: Chris Toomey 3 | " Description: Markdown formatted link search, copy&paste and opening. 4 | " Last Modified: February 17, 2015 5 | 6 | let s:MARKDOWN_LINK_SYNTAX_IDS = [ 7 | \ "markdownLinkText", 8 | \ "markdownLinkTextDelimiter", 9 | \ "markdownIdDeclaration", 10 | \ "mkdLink", 11 | \ "mkdDelimiter", 12 | \ "mkdLinkDef" 13 | \ ] 14 | 15 | function! ConvertVisualSelectionToLink(...) 16 | if a:0 == 0 17 | normal! gv"vy 18 | call s:SearchForTerm() 19 | return 20 | else 21 | let url = a:1 22 | endif 23 | normal! gv 24 | normal! mm 25 | execute 'normal! "lc[l][]' 26 | let current_line = line('.') 27 | let markdown_h2_pattern = '\v^(\w+.*\n-+|#{2,3}\s+\w+)' 28 | let next_match_line = search(markdown_h2_pattern) 29 | if next_match_line == 0 || next_match_line < current_line 30 | let target_line = line('$') 31 | else 32 | let target_line = next_match_line - 2 33 | endif 34 | let formatted_link = '[' . @l . ']: ' . url 35 | call append(target_line, formatted_link) 36 | call s:EnsureLineAbove(target_line) 37 | normal! `m 38 | endfunction 39 | 40 | function! s:SearchForTerm() 41 | let search_prompt = "Search term (leave blank to use clipboard): " 42 | echohl String | let term = input(search_prompt, @v) | echohl None 43 | if term == '' 44 | call ConvertVisualSelectionToLink(system('pbpaste')) 45 | return 46 | endif 47 | let encoded_term = webapi#http#encodeURI(term) 48 | let api_url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&filter=1&rsz=small&q=' 49 | let request_url = api_url . encoded_term 50 | let response = webapi#http#get(request_url) 51 | let content = webapi#json#decode(response.content) 52 | let results = content.responseData.results 53 | call s:DisplaySearchResults(results) 54 | endfunction 55 | 56 | function! s:DisplaySearchResults(results) 57 | let g:search_results = a:results 58 | let map_expression = '[v:val.url, " -> " .v:val.titleNoFormatting, ""]' 59 | let formatted = s:Flatten(map(copy(a:results), map_expression)) 60 | silent pedit search-results 61 | wincmd P 62 | setlocal buftype=nofile 63 | setlocal noswapfile 64 | setlocal nowrap 65 | nnoremap q :q! 66 | nnoremap :call SelectSearchResult() 67 | nnoremap :normal! gx 68 | nnoremap 2j 69 | nnoremap 2k 70 | nnoremap :call search('^\S'):noh 71 | nnoremap :call search('^\S', 'b'):noh 72 | nnoremap o :normal! gx 73 | normal! ggdG 74 | call append(0, formatted) 75 | normal! ddgg 76 | endfunction 77 | 78 | function! s:EnsureLineAbove(target_line) 79 | if !s:ContentsAreEmptyOrLink(getline(a:target_line)) 80 | call append(a:target_line, '') 81 | endif 82 | endfunction 83 | 84 | function! s:ContentsAreEmptyOrLink(contents) 85 | let contents_are_link = match(a:contents, '\v\[.*\]:\s') 86 | return (a:contents == '') || (contents_are_link != -1) 87 | endfunction 88 | 89 | function! s:Flatten(list) 90 | let val = [] 91 | for elem in a:list 92 | if type(elem) == type([]) 93 | call extend(val, s:Flatten(elem)) 94 | else 95 | call add(val, elem) 96 | endif 97 | unlet elem 98 | endfor 99 | return val 100 | endfunction 101 | 102 | function! SelectSearchResult() 103 | let selected = g:search_results[line('.') / 3].url 104 | bdelete 105 | call ConvertVisualSelectionToLink(selected) 106 | endfunction 107 | 108 | function! s:OnMarkdownLink() 109 | let current_syntax_id = synIDattr(synID(line("."), col("."), 1), "name") 110 | return count(s:MARKDOWN_LINK_SYNTAX_IDS, current_syntax_id) != 0 111 | endfunction 112 | 113 | function! s:CaptureLinkText() 114 | let @a = "" 115 | normal! "ayi] 116 | return escape(getreg('a'), '&') 117 | endfunction 118 | 119 | function! s:OpenWithNetrw() 120 | if has("patch-7.4.567") 121 | call netrw#BrowseX(expand(""),0) 122 | else 123 | call netrw#NetrwBrowseX(expand(""),0) 124 | endif 125 | endfunction 126 | 127 | function! s:GoToLinkDefinition(link_name) 128 | let link_target_pattern = '\v^\['.a:link_name.'\]: (%(ftp[s]?|http[s]?):\/\/\S+)>' 129 | let found = search(link_target_pattern, 'ce') 130 | normal! B 131 | return found 132 | endfunction 133 | 134 | function! s:OpenMarkdownLink() 135 | let initial_pos = getpos('.') 136 | let escaped_link_name = s:CaptureLinkText() 137 | if s:GoToLinkDefinition(escaped_link_name) 138 | call s:OpenWithNetrw() 139 | endif 140 | call setpos('.', initial_pos) 141 | endfunction 142 | 143 | function! s:MarkdownAwareGX() 144 | if s:OnMarkdownLink() 145 | call s:OpenMarkdownLink() 146 | else 147 | call s:OpenWithNetrw() 148 | endif 149 | endfunction 150 | 151 | command! MarkdownAwareGX call MarkdownAwareGX() 152 | nnoremap gx :MarkdownAwareGX 153 | 154 | command! GoToLinkDefinition call GoToLinkDefinition(CaptureLinkText()) 155 | nnoremap gl :GoToLinkDefinition 156 | 157 | vnoremap :call ConvertVisualSelectionToLink() 158 | -------------------------------------------------------------------------------- /overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christoomey/vim-quicklink/021167741588555501594e1fc31f130b16acefa0/overview.gif --------------------------------------------------------------------------------