├── LICENSE
├── README.md
├── autoload
└── vimbits
│ ├── highlightonyank.vim
│ ├── jump.vim
│ └── vim9cmdline.vim
├── doc
├── easyjump.txt
├── fFtT.txt
├── tags
└── vimtips.txt
├── plugin
├── easyjump.vim
├── fFtT.vim
└── vimbits.vim
└── test
├── highlight.vim
├── runtests.sh
├── setup.vim
├── visual.vim
└── yank.vim
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 girishji
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 | # VimBits
2 |
3 | Suite of lightweight Vim plugins.
4 |
5 | 1. [**HighlightOnYank**](#plugin-highlightonyank) - Confirm yank operation by temporarily highlighting the region.
6 |
7 | 2. [**EasyJump**](#plugin-easyjump) - Jump to any location on screen by typing two characters.
8 |
9 | 3. [**fFtT**](#plugin-fFtT) - Highlight characters reachable in one jump using `f`, `t`, `F`, and `T` commands.
10 |
11 | 4. [**Vim9Cmdline**](#plugin-vim9cmdline) - Use *vim9script* in command-line seamlessley.
12 |
13 | 5. **vimtips** from [zzapper](https://web.archive.org/web/20121104092340/http://zzapper.co.uk/vimtips.html) - `:h vimtips.txt`
14 |
15 |
16 | ## Requirements
17 |
18 | - Vim 9.0 or higher
19 |
20 | ## Installation
21 |
22 | Install it via [vim-plug](https://github.com/junegunn/vim-plug).
23 |
24 | Show instructions
25 |
26 |
27 | Using vim9 script:
28 |
29 | ```vim
30 | vim9script
31 | plug#begin()
32 | Plug 'girishji/vimbits'
33 | plug#end()
34 | ```
35 |
36 | Using legacy script:
37 |
38 | ```vim
39 | call plug#begin()
40 | Plug 'girishji/vimbits'
41 | call plug#end()
42 | ```
43 |
44 |
45 |
46 | Install using Vim's built-in package manager.
47 |
48 | Show instructions
49 |
50 |
51 | ```bash
52 | $ mkdir -p $HOME/.vim/pack/downloads/opt
53 | $ cd $HOME/.vim/pack/downloads/opt
54 | $ git clone https://github.com/girishji/vimbits.git
55 | ```
56 |
57 | Add the following to your $HOME/.vimrc file.
58 |
59 | ```vim
60 | packadd vimbits
61 | ```
62 |
63 |
64 |
65 | ## Configuration
66 |
67 | By default, all plugins are enabled except for Vim9Cmdline. To disable a specific plugin, set its corresponding global variable to `false`. To enable a plugin, set its corresponding global variable to `true`.
68 |
69 | ```
70 | vim9script
71 | g:vimbits_highlightonyank = true
72 | g:vimbits_easyjump = true
73 | g:vimbits_fFtT = true
74 | g:vimbits_vim9cmdline = false
75 | ```
76 |
77 | More configurable options pertaining to individual plugins are described below.
78 |
79 | # Plugin: HighlightOnYank
80 |
81 | Ensure the text you intended to yank is correctly selected. This feature helps avoid surprises when pasting, especially if you accidentally hit the wrong keys.
82 |
83 | The yanked region is temporarily highlighted (using `:h hl-IncSearch`) for 300 milliseconds by default. The duration and highlight group are configurable, and there's an option to disable highlighting in visual mode.
84 |
85 | To customize the default settings, add the following to your `.vimrc` file:
86 |
87 | ```vim
88 | vim9script
89 | g:vimbits_highlightonyank = false # Disables the default autocmd
90 | import autoload 'vimbits/highlightonyank.vim' as hy
91 | augroup HighlightOnYank
92 | autocmd!
93 | autocmd TextYankPost * hy.HighlightOnYank('IncSearch', 300, true)
94 | augroup END
95 | ```
96 |
97 | `HighlightOnYank()` accepts three arguments:
98 |
99 | - `hlgroup`: The highlight group for the yanked region.
100 | - `duration`: The duration of the highlight in milliseconds.
101 | - `in_visual`: Whether to highlight the region when yanked in visual mode.
102 |
103 | This mini plugin is inspired by [this issue](https://github.com/vim/vim/issues/14848).
104 |
105 | # Plugin: EasyJump
106 |
107 | Jump to any location on screen by typing two characters.
108 |
109 | ## TL;DR
110 |
111 | - `s` + _\_ + _\_ to jump
112 | - `ds` + _\_ + _\_ to delete (similarly, `vs` for visual selection, `cs` for change, etc.)
113 | - `` and `` (or `;` and `,`) after _\_ to view additional tag characters
114 | - `2s` + _\_ + _\_ + _\_ to jump
115 |
116 | ## Features
117 |
118 | - Initially bound to `s`, but it can be reassigned to any desired trigger (e.g., `,`).
119 | - Supports essential Vim idioms such as `ds` for deletion, `cs` for change, `vs` for visual selection, and more. Here `s` is the trigger character.
120 | - Updates the jump list (`:jumps`) for easy back-navigation using ``.
121 | - Optional two-character mode, for users accustomed to targeting with two characters instead of one.
122 | - Non-disruptive: Does not modify the buffer. Crafted in vim9 script.
123 |
124 |
125 | 🚀 **Jump (`s`)**: Type `s` followed by a character (say `c`). Witness
126 | new tag characters replacing the character `c`. Typing next
127 | character initiates the jump. For instance, typing `e`
128 | navigates the cursor to the `c` under `e`.
129 |
130 |
131 |
132 | 🚀 **Jump back**: Type `` (control-O) to jump back. Type `` or `` to jump forward.
133 |
134 | 🚀 **Visual Select (`vs`)**: For visually selecting a block of text from the
135 | cursor position up to an instance of `c`, enter `vsc`, then the highlighted
136 | character (e.g., `e`).
137 |
138 |
139 |
140 | Likewise, use `ds` for deletion or `cs` for text alteration.
141 |
142 | Press `` to cancel the ongoing jump.
143 |
144 | Pictures above are based on `:colorscheme quiet`.
145 |
146 | 🔎 **What if the intended jump location is not showing a tag letter?**
147 |
148 | This scenario occurs when there aren't enough unique letters available for
149 | tagging. Simply press `` (or `;`), and new tag labels will fill the
150 | remaining spots. To cycle backwards, press `` (or `,`).
151 |
152 | 🚀 **Two-Character Mode (New)**: Activated with `2s` or simply `s` if `g:easyjump_two_chars` is configured as `true`.
153 |
154 | - Use `2s` + _\_ + _\_ to leap to your destination (when a tag character marks the spot).
155 | - If no tag label is present, type the adjacent character as well, forming `2s` + _\_ + _\_ + _\_ to execute the jump.
156 |
157 | > [!TIP]
158 | > A lazy way to navigate is by leveraging the space character as a guide. Experiment with typing `s` followed by ``. The algorithm strives to allocate one label per line. Once you're near your desired location within a line, you can [effectively employ](https://github.com/girishji/fFtT.vim) Vim's built-in `f/F, t/T` commands to reach it precisely. This is an alternative to using relative line numbers to jump.
159 |
160 | ## Trigger Key
161 |
162 | By default, `s` serves as the trigger key. To unmap `s` and restore it to the default (:h s),
163 | include the following line in your .vimrc file:
164 |
165 | ```
166 | g:easyjump_default_keymap = false
167 | ```
168 |
169 | To assign `,` as the trigger for jumping, add the following lines to your `.vimrc`
170 | file. You can choose any other key beside `,`.
171 |
172 | ```
173 | nmap , EasyjumpJump;
174 | omap , EasyjumpJump;
175 | vmap , EasyjumpJump;
176 | ```
177 |
178 | ## Case Sensitivity
179 |
180 | Options include 'case' (case sensitive), 'icase' (ignore case), or 'smart'
181 | (smart case). Add the following line to your .vimrc:
182 |
183 | ```
184 | g:easyjump_case = 'smart' # Can be 'case', 'icase', or 'smart' (default).
185 | ```
186 |
187 | ## Highlight Group
188 |
189 | The tag letters displayed alongside destination locations utilize the
190 | highlighted group `EasyJump`. By default, this group is linked to `IncSearch`. Modify its
191 | appearance using the `:highlight` command to change colors.
192 |
193 | ## Tag Letters
194 |
195 | Jump locations prioritize placement based on distance from cursor and
196 | preference for having at least one placement per line.
197 | Letters are picked in the following sequence. Modify the sequence (say, for
198 | Dvorak) as needed. Set the following global variable:
199 |
200 | ```
201 | g:easyjump_letters = 'asdfgwercvhjkluiopynmbtqxzASDFGWERCVHJKLUIOPYNMBTQXZ0123456789'
202 | ```
203 |
204 | # Plugin: fFtT
205 |
206 | Characters that are reachable with a single jump are highlighted, while others are dimmed. This enhancement enhances the accuracy of navigation using `f`, `F`, `t`, and `T` commands. Moreover, you can prefix the command with a numerical `[count]` (e.g., `3f`), which will exclusively highlight the `[count]`'th occurrence (third in this instance) of a character to the right of the cursor, while dimming the others.
207 |
208 | This plugin does not alter Vim operators or commands. It solely focuses on highlighting relevant characters without making any changes to the default key mappings. The code consists of less than 100 lines, with explanatory comments.
209 |
210 | 
211 |
212 | The appearance of characters that are unreachable within one jump is determined by the highlight group `FfTtSubtle`, which is linked to the `Comment` group by default.
213 |
214 | # Plugin: Vim9Cmdline
215 |
216 | *vim9script* offers significant improvements over the legacy script. Although there isn't a direct way to switch the command line to parse *vim9script*, you can execute *vim9script* commands by prepending each command with `vim9`. This plugin automates that process for you.
217 |
218 |
219 |
220 | Some things to keep in mind:
221 |
222 | - Remember that execution occurs in the global context, not the script-local context. This means you need to declare variables with the `g:` prefix, like `g:foo = 'bar'`.
223 |
224 | - Common commands, such as visual range (`'<,'>`), other types of ranges, shell commands (`!`), substitution (`s//`), and global (`g//`), work as expected even when `vim9` is prepended.
225 |
226 | - Ranges to Ex commands should be prefixed with a colon. For example, `:vim9 :%s/foo/bar` (notice the `:` before `%s`).
227 | From `:h [range]`:
228 |
229 | > In Vim9 script a range needs to be prefixed with a colon to avoid ambiguity
230 | > with continuation lines.
231 |
232 | - Related to the above, if your keymap's right-hand side (rhs) starts with a range, it may throw an error. To avoid this, use `:h ` or ensure the {rhs} of your keymap begins with `silent` or `:`. For example, `nnoremap your_key :% !your_cmd` throws an error, while `nnoremap your_key % !your_cmd`, `nnoremap your_key :silent % !your_cmd` and `nnoremap your_key ::% !your_cmd` are OK.
233 |
234 | - Colorschemes may not load if they are written in legacy script. `:vim9 colorscheme foo` will not work unless `foo` is written in vim9script.
235 |
236 | - If you have defined a custom command with a completion function (`command -complete=custom,Foo() ...`), be aware that this function may not work as expected if it is designed to complete the n-th word. This is because there are now n+1 words, including the word `vim9`. You many need to adapt this function.
237 |
238 | - If you work with multi-byte UTF-8 characters, you'll appreciate the *vim9* command line. When slicing a UTF-8 string using the `[from : to]` operator, *vim9* is more predictable because it uses character-based addressing, unlike the byte-based addressing of the legacy script.
239 |
240 | - Legacy mode of addressing autoloaded functions and variables still work, even without legacy keywords like `call` and `let`. For instance, both `:vim9 g:foo#bar#baz()` and `:vim9 call g:foo#bar#baz()` work.
241 |
242 | You can keep the command line in *vim9script* mode by default and switch back to the legacy script at any time using the `:ToggleVim9Cmdline` command.
243 |
244 | ## Other Plugins to Enhance Your Workflow
245 |
246 | 1. [**vimcomplete**](https://github.com/girishji/vimcomplete) - enhances autocompletion in Vim.
247 |
248 | 2. [**devdocs.vim**](https://github.com/girishji/devdocs.vim) - browse documentation from [devdocs.io](https://devdocs.io).
249 |
250 | 3. [**scope.vim**](https://github.com/girishji/scope.vim) - fuzzy find anything.
251 |
252 | 4. [**VimSuggest**](https://github.com/girishji/vimsuggest) - autocompletion for Vim's command-line.
253 |
--------------------------------------------------------------------------------
/autoload/vimbits/highlightonyank.vim:
--------------------------------------------------------------------------------
1 | vim9script
2 |
3 | # hlgroup: Highlight group used for highlighting yanked region.
4 | # duration: Duration of highlight in milliseconds.
5 | # in_visual: Whether to highlight the region if selected from visual mode.
6 | export def HighlightOnYank(hlgroup = 'IncSearch', duration = 300, in_visual = true)
7 | if v:event.operator ==? 'y'
8 | if !in_visual && visualmode() != null_string
9 | visualmode(1)
10 | return
11 | endif
12 | var [beg, end] = [getpos("'["), getpos("']")]
13 | var type = v:event.regtype ?? 'v'
14 | var pos = getregionpos(beg, end, {type: type})
15 | var end_offset = (type == 'V' || v:event.inclusive) ? 1 : 0
16 | var m = matchaddpos(hlgroup, pos->mapnew((_, v) => {
17 | var col_beg = v[0][2] + v[0][3]
18 | var col_end = v[1][2] + v[1][3] + end_offset
19 | return [v[0][1], col_beg, col_end - col_beg]
20 | }))
21 | var winid = win_getid()
22 | timer_start(duration, (_) => {
23 | # keymap like `:vmap // y/"` (search for visually selected text) throws E803
24 | try
25 | m->matchdelete(winid)
26 | catch
27 | endtry
28 | })
29 | endif
30 | enddef
31 |
32 | export def HighlightOnYankLegacy(hlgroup = 'IncSearch', duration = 300, in_visual = true)
33 | if v:event.operator ==? 'y'
34 | if !in_visual && visualmode() != null_string
35 | visualmode(1)
36 | return
37 | endif
38 | var [lnum_beg, col_beg, off_beg] = getpos("'[")[1 : 3]
39 | var [lnum_end, col_end, off_end] = getpos("']")[1 : 3]
40 | col_end += !v:event.inclusive ? 1 : 0
41 | var maxcol = v:maxcol - 1
42 | var visualblock = v:event.regtype[0] ==# "\"
43 | var pos = []
44 | for lnum in range(lnum_beg, lnum_end, lnum_beg < lnum_end ? 1 : -1)
45 | var col_b = (lnum == lnum_beg || visualblock) ? (col_beg + off_beg) : 1
46 | var col_e = (lnum == lnum_end || visualblock) ? (col_end + off_end) : maxcol
47 | pos->add([lnum, col_b, min([col_e - col_b + 1, maxcol])])
48 | endfor
49 | var m = matchaddpos(hlgroup, pos)
50 | var winid = win_getid()
51 | timer_start(duration, (_) => {
52 | try
53 | m->matchdelete(winid)
54 | catch
55 | endtry
56 | })
57 | endif
58 | enddef
59 |
--------------------------------------------------------------------------------
/autoload/vimbits/jump.vim:
--------------------------------------------------------------------------------
1 | vim9script
2 |
3 | var locations: list> = [] # A list of {line nr, column nr} to jump to
4 | var letters: string
5 | var labels: string
6 | var easyjump_case: string
7 |
8 | export def Setup()
9 | easyjump_case = get(g:, 'easyjump_case', 'smart') # case/icase/smart
10 | letters = get(g:, 'easyjump_letters', '')
11 | if letters->empty()
12 | var alpha = 'asdfgwercvhjkluiopynmbtqxz'
13 | letters = $'{alpha}{alpha->toupper()}0123456789'
14 | endif
15 | if letters->split('\zs')->sort()->uniq()->len() != letters->len()
16 | echoe 'EasyJump: Letters list has duplicates'
17 | endif
18 | # if get(g:, 'easyjump_default_keymap', true) && !hasmapto('EasyjumpJump;', 'n') && mapcheck('s', 'n') ==# ''
19 | if get(g:, 'easyjump_default_keymap', true)
20 | :nmap s EasyjumpJump;
21 | :omap s EasyjumpJump;
22 | :vmap s EasyjumpJump;
23 | endif
24 | enddef
25 |
26 | # get all line numbers in the visible area of the window ordered by distance from cursor
27 | def WindowLineNrs(): list
28 | # line('w$') does not include a long line (broken into many lines) that is only partly visible
29 | var [lstart, lend] = [max([1, line('w0')]), min([line('w$') + 1, line('$')])] # lines on screen
30 | var [curline, curcol] = getcurpos()[1 : 2]
31 | var lnums = [curline]
32 | for dist in range(1, (lend - lstart))
33 | if curline + dist <= lend
34 | lnums->add(curline + dist)
35 | endif
36 | if curline - dist >= lstart
37 | lnums->add(curline - dist)
38 | endif
39 | endfor
40 | return lnums
41 | enddef
42 |
43 | # search for locations to jump to, starting from cursor position and searching outwards
44 | def GatherLocations(ctx: string, filter_label: bool = false)
45 | var ignorecase = (easyjump_case ==? 'icase' || (easyjump_case ==? 'smart' && ctx =~ '\U')) ? true : false
46 | var Ignorecase = (s) => ignorecase ? s->tolower() : s
47 | labels = letters->copy()
48 | locations = []
49 |
50 | var [curline, curcol] = getcurpos()[1 : 2]
51 | var lnums = WindowLineNrs()
52 | for lnum in lnums
53 | if foldclosed(lnum) != -1
54 | continue # ignore folded lines
55 | endif
56 | var line = Ignorecase(getline(lnum))
57 | var col = line->stridx(ctx)
58 | while col != -1
59 | col += 1 # column numbers start from 1
60 | if ctx == ' ' && !locations->empty() && locations[-1] == [lnum, col - 1]
61 | locations[-1][1] = col # one target per cluster of adjacent spaces
62 | elseif [lnum, col] != [curline, curcol] # no target on cursor position
63 | locations->add([lnum, col])
64 | if filter_label && col < line->len()
65 | # remove character next to ctx from label chars
66 | var idx = labels->stridx(line[col])
67 | if idx != -1
68 | labels = $'{labels->slice(0, idx)}{labels->slice(idx + 1)}'
69 | endif
70 | endif
71 | endif
72 | col = line->stridx(ctx, col)
73 | endwhile
74 | if lnum == curline # prioritize based on distance from cursor
75 | locations->sort((x, y) => abs(x[1] - curcol) - abs(y[1] - curcol))
76 | endif
77 | endfor
78 | enddef
79 |
80 | # order locations list by keeping more locations near cursor, and at least one per line
81 | def Prioritize()
82 | var [lstart, lend] = [line('w0'), line('w$')] # lines on screen start/end
83 | var highpri = []
84 | var lowpri = []
85 | var expected = locations->len()
86 | var curline = line('.')
87 | def FilterLocations(tlinenr: number, tmax: number)
88 | if tlinenr < lstart || tlinenr > lend
89 | return
90 | endif
91 | var curlocations = locations->copy()->filter((_, v) => v[0] == tlinenr)
92 | locations->filter((_, v) => v[0] != tlinenr)
93 | highpri->extend(curlocations->slice(0, tmax))
94 | lowpri->extend(curlocations->slice(tmax))
95 | enddef
96 |
97 | FilterLocations(curline, 10) # 10 locations max
98 | if locations->len() > (lend - lstart)
99 | var excess = locations->len() - (lend - lstart)
100 | FilterLocations(curline + 1, excess / 3)
101 | FilterLocations(curline - 1, excess / 3)
102 | endif
103 | # at least one target per line
104 | for p in range(locations->len())
105 | if locations[p][0] != locations[p - 1][0]
106 | highpri->add(locations[p])
107 | else
108 | lowpri->add(locations[p])
109 | endif
110 | endfor
111 | # shuffle the remaining low priority locations
112 | lowpri = lowpri->mapnew((_, v) => [v, rand()])->sort((a, b) => a[1] < b[1] ? 0 : 1)->mapnew((_, v) => v[0])
113 | locations = highpri + lowpri
114 | # error check
115 | if expected != locations->len()
116 | echoe 'EasyJump: Locations list filter error'
117 | endif
118 | if locations->copy()->sort()->uniq()->len() != locations->len()
119 | echoe 'EasyJump: Locations list has duplicates'
120 | endif
121 | enddef
122 |
123 | def ShowTag(tag: string, lnum: number, col: number)
124 | if lnum != -1
125 | popup_create(tag, {
126 | line: lnum,
127 | col: col,
128 | highlight: 'EasyJump',
129 | wrap: false,
130 | zindex: 50 - 1,
131 | })
132 | endif
133 | enddef
134 |
135 | # NOTE: column number (byte based) is different from screen column when tab or
136 | # utf-8 chars are present. chars like ぬ, і, etc. are 3-byte and double wide.
137 | # popup_create() expects screen column while what we have is byte column. Use
138 | # screenpos() with synconcealed(), or wincol() which requires :redraw and is slow.
139 | # Vim bug: https://github.com/vim/vim/issues/14640
140 | # concealed characters, set by matchadd() are not accounted for.
141 | # https://github.com/vim/vim/issues/14643
142 |
143 | def ScreenPos(lnum: number, col: number): list
144 | var is_invisible = {row: 0, col: 0, endcol: 0, curscol: 0}
145 | var scrpos = win_getid()->screenpos(lnum, col)
146 | if scrpos != is_invisible
147 | # screenpos has no knowledge of concealed or substituted chars
148 | var concealed_len = 0
149 | var idx = 1
150 | while idx < col
151 | var status = synconcealed(lnum, idx)
152 | if status[0] == 1 # concealed
153 | var spos = win_getid()->screenpos(lnum, idx)
154 | var clen = spos.endcol - spos.col + 1
155 | if status[1] != null_string # substitute char present
156 | echom status[1]
157 | # Vim does not allow/show as substitute char
158 | # utf-8 chars are either 1 cell or 2 cell wide
159 | clen -= status[1]->strwidth() # display width in cells
160 | endif
161 | concealed_len += clen
162 | var line = getline(lnum)
163 | idx += line->strcharpart(line->charidx(idx - 1), 1)->len() # skip by byte width of char
164 | else
165 | idx += 1
166 | endif
167 | endwhile
168 | return [scrpos.row, scrpos.col - concealed_len]
169 | endif
170 | return [-1, -1]
171 | enddef
172 |
173 | def ShowLocations(group: number)
174 | try
175 | popup_clear()
176 | var ntags = labels->len()
177 | for idx in range(min([ntags, locations->len() - group * ntags]))
178 | var [lnum, col] = locations[idx + group * ntags]
179 | var [scrlnum, scrcol] = ScreenPos(lnum, col)
180 | if scrlnum != -1
181 | ShowTag(labels[idx], scrlnum, scrcol)
182 | endif
183 | endfor
184 | finally
185 | :redraw
186 | endtry
187 | enddef
188 |
189 | def JumpTo(tgt: string, group: number)
190 | var tagidx = labels->stridx(tgt)
191 | var locidx = tagidx + group * labels->len()
192 | if tagidx != -1 && locidx < locations->len()
193 | var loc = locations[locidx]
194 | :normal! m'
195 | cursor(loc)
196 | endif
197 | popup_clear()
198 | enddef
199 |
200 | def GroupCount(): number
201 | var ngroups = locations->len() / labels->len() + 1
202 | ngroups -= (locations->len() % labels->len() == 0) ? 1 : 0
203 | if ngroups > 1
204 | Prioritize()
205 | endif
206 | return ngroups
207 | enddef
208 |
209 | # main entry point
210 | export def Jump(two_chars: bool = false)
211 | var two_chars_mode = two_chars || get(g:, 'easyjump_two_chars', false)
212 | var ch = (easyjump_case ==? 'icase') ? getcharstr()->tolower() : getcharstr()
213 | GatherLocations(ch, two_chars_mode)
214 | if locations->empty()
215 | return
216 | endif
217 | var ngroups = GroupCount()
218 | var group = 0
219 | try
220 | ShowLocations(group)
221 | var ctx = ch
222 | ch = getcharstr()
223 | if two_chars_mode
224 | if labels->stridx(ch) != -1
225 | JumpTo(ch, group)
226 | return
227 | elseif [';', ',', "\", "\"]->index(ch) != -1 # switch to 1-char mode
228 | labels = letters->copy()
229 | ngroups = GroupCount()
230 | if ngroups == 1
231 | ShowLocations(group)
232 | endif
233 | else
234 | ctx ..= (easyjump_case ==? 'icase') ? ch->tolower() : ch
235 | GatherLocations(ctx)
236 | ngroups = GroupCount()
237 | ShowLocations(group)
238 | ch = getcharstr()
239 | endif
240 | endif
241 | while true
242 | if [';', ',', "\", "\"]->index(ch) != -1
243 | if ngroups > 1
244 | if ch == ';' || ch == "\"
245 | group = (group + 1) % ngroups
246 | else
247 | group = (group + ngroups - 1) % ngroups
248 | endif
249 | ShowLocations(group)
250 | endif
251 | else
252 | JumpTo(ch, group)
253 | break
254 | endif
255 | ch = getcharstr()
256 | endwhile
257 | finally
258 | popup_clear()
259 | endtry
260 | enddef
261 |
--------------------------------------------------------------------------------
/autoload/vimbits/vim9cmdline.vim:
--------------------------------------------------------------------------------
1 | vim9script
2 |
3 | export def Vim9cmdlineSet()
4 | if get(g:, 'vimbits_vim9cmdline', false)
5 | if visualmode() == null_string
6 | setcmdline('vim9 ')
7 | else
8 | setcmdline('vim9 :')
9 | visualmode(1)
10 | endif
11 | cnoremap vim9
12 | cnoremap
13 | cnoremap getcmdpos() > 6 ? "\" : ""
14 | cnoremap getcmdpos() > 6 ? "\" : ""
15 | cnoremap getcmdpos() > 6 ? "\" : ""
16 | cnoremap getcmdpos() > 6 ? "\" : ""
17 | endif
18 | enddef
19 |
20 | export def Vim9cmdlineUnset()
21 | if get(g:, 'vimbits_vim9cmdline', false)
22 | silent! cunmap
23 | silent! cunmap
24 | silent! cunmap
25 | silent! cunmap
26 | silent! cunmap
27 | silent! cunmap
28 | endif
29 | enddef
30 |
--------------------------------------------------------------------------------
/doc/easyjump.txt:
--------------------------------------------------------------------------------
1 | *easyjump.txt* Vim motion on steroids
2 |
3 | Author: Girish (girishji AT gmail DOT com)
4 | For Vim version 9.0 and above
5 |
6 | ==============================================================================
7 | CONTENTS *easyjump-contents*
8 |
9 | 1. Overview ................................. |easyjump-overview|
10 | 2. Features ................................. |easyjump-features|
11 | 3. Requirements ............................. |easyjump-requirements|
12 | 4. Installation ............................. |easyjump-installation|
13 | 5. Configuration ............................ |easyjump-configuration|
14 |
15 | ==============================================================================
16 | 1. Overview *easyjump-overview*
17 |
18 | Jump to any location by typing 2 characters.
19 |
20 | Jump: Type `s` and `c` (say) and you'll see new letters (virtual text) appear
21 | next to all the occurrences of `c`. Type `d` (for instance) and cursor jumps to
22 | `c` next to `d`.
23 |
24 | Visual Select: To visually select a block of text starting from cursor position
25 | to some occurrence of `c` type `vsc` and then type the highlighted character
26 | (say `d`).
27 |
28 | What if there is no letter next to where you want to jump to?~
29 |
30 | This scenario occurs when there aren't enough unique letters available for
31 | tagging. Simply press `` (or `;`), and new tag labels will fill the
32 | remaining spots. To cycle backwards, press `` (or `,`).
33 |
34 | Two-Character Mode (New): Activated with `2s` or simply `s` if
35 | `g:easyjump_two_chars` is configured as `true`.
36 | - Use `2s` + + to leap to your destination (when a
37 | tag character marks the spot).
38 | - If no tag label is present, type the adjacent character as well, forming
39 | `2s` + + + _tag_character_ to execute the jump.
40 |
41 | ==============================================================================
42 | 2. Features *easyjump-features*
43 |
44 | - Mapped to `s` but any other trigger (like `,`) would work.
45 | - Vim idioms supported. Use `dsxy` to delete, `csxy` to change, `vsxy` to select visually, etc.
46 | - Jump list (`:jumps`) updated so that you can jump back using ``.
47 | - Does not alter the buffer.
48 |
49 | ==============================================================================
50 | 3. Requirements *easyjump-requirements*
51 |
52 | - Vim >= 9.0
53 |
54 | ==============================================================================
55 | 4. Installation *easyjump-installation*
56 |
57 | Install using vim-plug (https://github.com/junegunn/vim-plug).
58 | >
59 | vim9script
60 | plug#begin()
61 | Plug 'girishji/easyjump.vim'
62 | plug#end()
63 |
64 | Alternately,
65 | >
66 | call plug#begin()
67 | Plug 'girishji/easyjump.vim'
68 | call plug#end()
69 |
70 | Or use Vim's builtin package manager.
71 | >
72 | $ mkdir -p $HOME/.vim/pack/downloads/opt
73 | $ cd $HOME/.vim/pack/downloads/opt
74 | $ git clone https://github.com/girishji/easyjump.git
75 |
76 | If using builtin package manager, add the following line to your $HOME/.vimrc
77 | file:
78 | >
79 | packadd easyjump
80 |
81 | ==============================================================================
82 | 5. Configuration *easyjump-configuration*
83 |
84 | Trigger Key~
85 |
86 | By default `s` is the trigger key. To disable it put the following in `.vimrc`
87 | file. `s` will be restored to Vim original keybinding (`:h s`).
88 | >
89 | g:easyjump_default_keymap = false
90 |
91 | To make `,` (for example) trigger the jump put the following in `.vimrc` file.
92 | >
93 | nmap , EasyjumpJump;
94 | omap , EasyjumpJump;
95 | vmap , EasyjumpJump;
96 |
97 | Case~
98 |
99 | The destination character you type is compared against visible buffer text. To
100 | make the search case sensitive (case), insensitive (icase), or smart case
101 | (smart) put the following in `.vimrc`.
102 | >
103 | g:easyjump_case = 'smart' # Can be 'case', 'icase', or 'smart'
104 |
105 | Highlight~
106 |
107 | The tag letters that appear next to destination locations utilize highlight
108 | group `EasyJump`. It is linked to `MatchParen` by default. Set this group using
109 | `:highlight` command to change colors.
110 |
111 | Letters~
112 |
113 | The virtual text letters that appear next to the destination you want to jump
114 | to are prioritized based on distance from the cursor, with at least one letter
115 | per line. The letters appear in the following order of decreasing priority. The
116 | letters and order can be changed by assigning to the following variable.
117 | >
118 | g:easyjump_letters =
119 | 'asdfgwercvhjkluiopynmbtqxzASDFGWERCVHJKLUIOPYNMBTQXZ0123456789'
120 |
121 | ==============================================================================
122 |
123 | vim:tw=78:ts=8:noet:ft=help:norl:
124 |
--------------------------------------------------------------------------------
/doc/fFtT.txt:
--------------------------------------------------------------------------------
1 | fFtT.txt* Accurate left-right navigation in Vim
2 |
3 | Author: Girish (girishji AT gmail DOT com)
4 | For Vim version 9.0 and above
5 |
6 | ==============================================================================
7 | CONTENTS *fFtT-contents*
8 |
9 | 1. Overview ................................. |fFtT-overview|
10 | 2. Requirements ............................. |fFtT-requirements|
11 | 3. Installation ............................. |fFtT-installation|
12 | 4. Configuration............................. |fFtT-configuration|
13 |
14 | ==============================================================================
15 | 1. Overview *fFtT-overview*
16 |
17 | Characters that are reachable with a single jump are highlighted, while others
18 | are dimmed. This enhancement improves the accuracy of navigation using `f`,
19 | `F`, `t`, and `T` commands. Additionally, you can provide a numerical prefix
20 | (e.g., `3f`), which will only highlight characters that occur the third time
21 | to the right of the cursor, while others are dimmed.
22 |
23 | This plugin does not remap keys or alter the behavior of commands. It solely
24 | focuses on highlighting relevant characters without making any changes to the
25 | default key mappings. The code consists of less than 100 lines, with
26 | explanatory comments.
27 |
28 | ==============================================================================
29 | 2. Requirements *fFtT-requirements*
30 |
31 | - Vim >= 9.1
32 |
33 | ==============================================================================
34 | 3. Installation *fFtT-installation*
35 |
36 | Install using vim-plug (https://github.com/junegunn/vim-plug)
37 | >
38 | vim9script
39 | plug#begin()
40 | Plug 'girishji/fFtT.vim'
41 | plug#end()
42 |
43 | Legacy script:
44 | >
45 | call plug#begin()
46 | Plug 'girishji/fFtT.vim'
47 | call plug#end()
48 |
49 | Or use Vim's builtin package manager.
50 |
51 | ==============================================================================
52 | 4. Configuration *fFtT-configuration*
53 |
54 | The appearance of characters that are unreachable within one jump is
55 | determined by the highlight group `FfTtSubtle`, which is linked to the
56 | `Comment` group by default.
57 |
58 | ==============================================================================
59 |
60 | vim:tw=78:ts=8:noet:ft=help:norl:
61 |
--------------------------------------------------------------------------------
/doc/tags:
--------------------------------------------------------------------------------
1 | /Content.IE?/ vimtips.txt /*\/Content.IE?\/*
2 | easyjump-configuration easyjump.txt /*easyjump-configuration*
3 | easyjump-contents easyjump.txt /*easyjump-contents*
4 | easyjump-features easyjump.txt /*easyjump-features*
5 | easyjump-installation easyjump.txt /*easyjump-installation*
6 | easyjump-overview easyjump.txt /*easyjump-overview*
7 | easyjump-requirements easyjump.txt /*easyjump-requirements*
8 | easyjump.txt easyjump.txt /*easyjump.txt*
9 | fFtT-configuration fFtT.txt /*fFtT-configuration*
10 | fFtT-contents fFtT.txt /*fFtT-contents*
11 | fFtT-installation fFtT.txt /*fFtT-installation*
12 | fFtT-overview fFtT.txt /*fFtT-overview*
13 | fFtT-requirements fFtT.txt /*fFtT-requirements*
14 | vimtips-absolutely-essential vimtips.txt /*vimtips-absolutely-essential*
15 | vimtips-global vimtips.txt /*vimtips-global*
16 | vimtips-global-combined-with-substitute vimtips.txt /*vimtips-global-combined-with-substitute*
17 | vimtips-searching vimtips.txt /*vimtips-searching*
18 | vimtips-substitution vimtips.txt /*vimtips-substitution*
19 | vimtips.txt vimtips.txt /*vimtips.txt*
20 |
--------------------------------------------------------------------------------
/doc/vimtips.txt:
--------------------------------------------------------------------------------
1 | *vimtips.txt* For Vim version 8.0.
2 | David Rayner (zzapper) 15 Years of Vi + 7 years of Vim and still learning
3 | ------------------------------------------------------------------------------
4 | " new items marked [N] , corrected items marked [C]
5 | " *vimtips-searching*
6 | /joe/e : cursor set to End of match
7 | 3/joe/e+1 : find 3rd joe cursor set to End of match plus 1 [C]
8 | /joe/s-2 : cursor set to Start of match minus 2
9 | /joe/+3 : find joe move cursor 3 lines down
10 | /^joe.*fred.*bill/ : find joe AND fred AND Bill (Joe at start of line)
11 | /^[A-J]/ : search for lines beginning with one or more A-J
12 | /begin\_.*end : search over possible multiple lines
13 | /fred\_s*joe/ : any whitespace including newline [C]
14 | /fred\|joe : Search for FRED OR JOE
15 | /.*fred\&.*joe : Search for FRED AND JOE in any ORDER!
16 | /\/ : search for fred but not alfred or frederick [C]
17 | /\<\d\d\d\d\> : Search for exactly 4 digit numbers
18 | /\D\d\d\d\d\D : Search for exactly 4 digit numbers
19 | /\<\d\{4}\> : same thing
20 | /\([^0-9]\|^\)%.*% : Search for absence of a digit or beginning of line
21 | " finding empty lines
22 | /^\n\{3} : find 3 empty lines
23 | /^str.*\nstr : find 2 successive lines starting with str
24 | /\(^str.*\n\)\{2} : find 2 successive lines starting with str
25 | " using regexp memory in a search find fred.*joe.*joe.*fred
26 | /\(fred\).*\(joe\).*\2.*\1
27 | " Repeating the Regexp (rather than what the Regexp finds)
28 | /^\([^,]*,\)\{8}
29 | " visual searching
30 | :vmap // y/" : search for visually highlighted text
31 | :vmap // y/=escape(@", '\\/.*$^~[]') : with spec chars
32 | " \zs and \ze regex delimiters :h /\zs
33 | /<\zs[^>]*\ze> : search for tag contents, ignoring chevrons
34 | " zero-width :h /\@=
35 | /<\@<=[^>]*>\@= : search for tag contents, ignoring chevrons
36 | /<\@<=\_[^>]*>\@= : search for tags across possible multiple lines
37 | " searching over multiple lines \_ means including newline
38 | / : search for multiple line comments
39 | /fred\_s*joe/ : any whitespace including newline
40 | /bugs\(\_.\)*bunny : bugs followed by bunny anywhere in file
41 | :h \_ : help
42 | " search for declaration of subroutine/function under cursor
43 | :nmap gx yiw/^\(sub\function\)\s\+"
44 | " multiple file search/operations
45 | :bufdo /searchstr/ : use :rewind to recommence search
46 | " multiple file search better but cheating
47 | :bufdo %s/searchstr/&/gic : say n and then a to stop
48 | :bufdo execute "normal! @a" | w : execute macro a over all buffers [N]
49 | :bufdo exe ":normal Gp" | update : Paste to the end of each buffer [N]
50 | :argdo exe '%!sort' | w [N]
51 | " How to search for a URL without backslashing
52 | ?http://www.vim.org/ : (first) search BACKWARDS!!! clever huh!
53 | " Specify what you are NOT searching for (vowels)
54 | /\c\v([^aeiou]&\a){4} : search for 4 consecutive consonants
55 | /\%>20l\%<30lgoat : Search for goat between lines 20 and 30 [N]
56 | /^.\{-}home.\{-}\zshome/e : match only the 2nd occurence in a line of "home" [
57 | N]
58 | :%s/home.\{-}\zshome/alone : Substitute only the 2nd occurrence of home in any
59 | line [U]
60 | :%s/.*\zsone/two/ : Substitute only the LAST occurrence of one [N]
61 | " find str but not on lines containing tongue
62 | ^\(.*tongue.*\)\@!.*nose.*$
63 | \v^((tongue)@!.)*nose((tongue)@!.)*$
64 | .*nose.*\&^\%(\%(tongue\)\@!.\)*$
65 | :v/tongue/s/nose/&/gic
66 | 'a,'bs/extrascost//gc : trick: restrict search to between markers (answer
67 | n) [N]
68 | /integ : Control-L to complete search term [N]
69 | "----------------------------------------
70 | " *vimtips-substitution*
71 | :s/foo/\rfoo/g : \r will substitute a newline
72 | :%s/fred/joe/igc : general substitute command
73 | :%s//joe/igc : Substitute what you last searched for [N]
74 | :%s/~/sue/igc : Substitute your last replacement string [N]
75 | :%s/\r//g : Delete DOS returns ^M
76 | " Is your Text File jumbled onto one line? use following
77 | :%s/\r/\r/g : Turn DOS returns ^M into real returns
78 | :%s= *$== : delete end of line blanks
79 | :%s= \+$== : Same thing
80 | :%s#\s*\r\?$## : Clean both trailing spaces AND DOS returns
81 | :%s#\s*\r*$## : same thing
82 | " deleting empty lines
83 | :%s/^\n\{3}// : delete blocks of 3 empty lines
84 | :%s/^\n\+/\r/ : compressing empty lines
85 | :%s#<[^>]\+>##g : delete html tags, leave text (non-greedy)
86 | :%s#<\_.\{-1,}>##g : delete html tags possibly multi-line (non-greedy)
87 | :%s#.*\(\d\+hours\).*#\1# : Delete all but memorised string (\1) [N]
88 | " parse xml/soap
89 | %s#><\([^/]\)#>\r<\1#g : split jumbled up XML file into one tag per line [N
90 | ]
91 | %s/\r&/g : simple split of html/xml/soap [N]
92 | :%s#<[^/]#\rgic : simple split of html/xml/soap but not closing tag
93 | [N]
94 | :%s#<[^/]#\rgi : parse on open xml tag [N]
95 | :%s#\[\d\+\]#\rg : parse on numbered array elements [1] [N]
96 | ggVGgJ : rejoin XML without extra spaces (gJ) [N]
97 | %s=\\n#\d=\r&=g : parse PHP error stack [N]
98 | :%s#^[^\t]\+\t## : Delete up to and including first tab [N]
99 | " VIM Power Substitute
100 | :'a,'bg/fred/s/dick/joe/igc : VERY USEFUL
101 | " duplicating columns
102 | :%s= [^ ]\+$=&&= : duplicate end column
103 | :%s= \f\+$=&&= : Dupicate filename
104 | :%s= \S\+$=&& : usually the same
105 | " memory
106 | :%s#example#& = gic : duplicate entire matched string [N]
107 | :%s#.*\(tbl_\w\+\).*#\1# : extract list of all strings tbl_* from text [NC]
108 | :s/\(.*\):\(.*\)/\2 : \1/ : reverse fields separated by :
109 | :%s/^\(.*\)\n\1$/\1/ : delete duplicate lines
110 | :%s/^\(.*\)\(\n\1\)\+$/\1/ : delete multiple duplicate lines [N]
111 | " non-greedy matching \{-}
112 | :%s/^.\{-}pdf/new.pdf/ : delete to 1st occurence of pdf only (non-greedy)
113 | %s#^.\{-}\([0-9]\{3,4\}serial\)#\1#gic : delete up to 123serial or 1234serial [N
114 | ]
115 | " use of optional atom \?
116 | :%s#\<[zy]\?tbl_[a-z_]\+\>#\Lgc : lowercase with optional leading characters
117 | " over possibly many lines
118 | :%s/// : delete possibly multi-line comments
119 | :help /\{-} : help non-greedy
120 | " substitute using a register
121 | :s/fred/a/g : sub "fred" with contents of register "a"
122 | :s/fred/asome_texts/g
123 | :s/fred/\=@a/g : better alternative as register not displayed (not
124 | *) [C]
125 | :s/fred/\=@*/g : replace string with contents of paste register [N]
126 | " multiple commands on one line
127 | :%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/
128 | :%s/a/but/gie|:update|:next : then use @: to repeat
129 | " ORing
130 | :%s/goat\|cow/sheep/gc : ORing (must break pipe)
131 | :'a,'bs#\[\|\]##g : remove [] from lines between markers a and b [N]
132 | :%s/\v(.*\n){5}/&\r : insert a blank line every 5 lines [N]
133 | " Calling a VIM function
134 | :s/__date__/\=strftime("%c")/ : insert datestring
135 | :inoremap \zd =strftime("%d%b%y") : insert date eg 31Jan11 [N]
136 | " Working with Columns sub any str1 in col3
137 | :%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:
138 | " Swapping first & last column (4 columns)
139 | :%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:
140 | " format a mysql query
141 | :%s#\\|\\|\\|\<\inner join\>#\rg
142 | " filter all form elements into paste register
143 | :redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END
144 | :nmap ,z :redir @*sil exec 'g@<\(input\select\textarea\/\=fo
145 | rm\)\>@p'redir END
146 | " substitute string in column 30 [N]
147 | :%s/^\(.\{30\}\)xx/\1yy/
148 | " decrement numbers by 3
149 | :%s/\d\+/\=(submatch(0)-3)/
150 | " increment numbers by 6 on certain lines only
151 | :g/loc\|function/s/\d/\=submatch(0)+6/
152 | " better
153 | :%s#txtdev\zs\d#\=submatch(0)+1#g
154 | :h /\zs
155 | " increment only numbers gg\d\d by 6 (another way)
156 | :%s/\(gg\)\@<=\d\+/\=submatch(0)+6/
157 | :h zero-width
158 | " rename a string with an incrementing number
159 | :let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1 # convert yy to 10,11,12 etc
160 | " as above but more precise
161 | :let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # convert xxyy to xx11,xx12,
162 | xx13
163 | " find replacement text, put in memory, then use \zs to simplify substitute
164 | :%s/"\([^.]\+\).*\zsxx/\1/
165 | " Pull word under cursor into LHS of a substitute
166 | :nmap z :%s#\<=expand("")\>#
167 | " Pull Visually Highlighted text into LHS of a substitute
168 | :vmap z :%s/\<*\>/
169 | " substitute singular or plural
170 | :'a,'bs/bucket\(s\)*/bowl\1/gic [N]
171 | ----------------------------------------
172 | " all following performing similar task, substitute within substitution
173 | " Multiple single character substitution in a portion of line only
174 | :%s,\(all/.*\)\@<=/,_,g : replace all / with _ AFTER "all/"
175 | " Same thing
176 | :s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')#
177 | " Substitute by splitting line, then re-joining
178 | :s#all/#&^M#|s#/#_#g|-j!
179 | " Substitute inside substitute
180 | :%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/
181 | ----------------------------------------
182 | " *vimtips-global* command
183 | :g/gladiolli/# : display with line numbers (YOU WANT THIS!)
184 | :g/fred.*joe.*dick/ : display all lines fred,joe & dick
185 | :g/\/ : display all lines fred but not freddy
186 | :g/^\s*$/d : delete all blank lines
187 | :g!/^dd/d : delete lines not containing string
188 | :v/^dd/d : delete lines not containing string
189 | :g/joe/,/fred/d : not line based (very powerfull)
190 | :g/fred/,/joe/j : Join Lines [N]
191 | :g/-------/.-10,.d : Delete string & 10 previous lines
192 | :g/{/ ,/}/- s/\n\+/\r/g : Delete empty lines but only between {...}
193 | :v/\S/d : Delete empty lines (and blank lines ie whitespace)
194 | :v/./,/./-j : compress empty lines
195 | :g/^$/,/./-j : compress empty lines
196 | :g/ as 5 characters)
216 | :.,$g/^\d/exe "norm! \": increment numbers
217 | :'a,'bg/\d\+/norm! ^A : increment numbers
218 | " storing glob results (note must use APPEND) you need to empty reg a first with
219 | qaq.
220 | "save results to a register/paste buffer
221 | :g/fred/y A : append all lines fred to register a
222 | :g/fred/y A | :let @*=@a : put into paste buffer
223 | :g//y A | :let @*=@a : put into paste buffer # better reuses last g// [N]
224 | :g//y A | :let @*=@a : put last glob into paste buffer [N]
225 | :let @a=''|g/Barratt/y A |:let @*=@a
226 | " filter lines to a file (file must already exist)
227 | :'a,'bg/^Error/ . w >> errors.txt
228 | " duplicate every line in a file wrap a print '' around each duplicate
229 | :g/./yank|put|-1s/'/"/g|s/.*/Print '&'/
230 | " replace string with contents of a file, -d deletes the "mark"
231 | :g/^MARK$/r tmp.txt | -d
232 | " display prettily
233 | :g//z#.5 : display with context
234 | :g//z#.5|echo "==========" : display beautifully
235 | " Combining g// with normal mode commands
236 | :g/|/norm 2f|r* : replace 2nd | with a star
237 | "send output of previous global command to a new window
238 | :nmap :redir @a:g//:redir END:new:put! a
239 | ----------------------------------------
240 | " *vimtips-global-combined-with-substitute* (*power-editing*)
241 | :'a,'bg/fred/s/joe/susan/gic : can use memory to extend matching
242 | :/fred/,/joe/s/fred/joe/gic : non-line based (ultra)
243 | :/biz/,/any/g/article/s/wheel/bucket/gic: non-line based [N]
244 | ----------------------------------------
245 | " Find fred before beginning search for joe [N]
246 | /fred/;/joe/
247 | " Find fred before beginning search for joe then substitute [N]
248 | :/fred/;/joe/-2,/sid/+3s/sally/alley/gIC
249 | ----------------------------------------
250 | " create a new file for each line of file eg 1.txt,2.txt,3,txt etc
251 | :g/^/exe ".w ".line(".").".txt"
252 | ----------------------------------------
253 | " chain an external command
254 | :.g/^/ exe ".!sed 's/N/X/'" | s/I/Q/ [N]
255 | ----------------------------------------
256 | " Operate until string found [N]
257 | d/fred/ :delete until fred
258 | y/fred/ :yank until fred
259 | c/fred/e :change until fred end
260 | v12| : visualise/change/delete to column 12 [N
261 | ]
262 | ----------------------------------------
263 | " Summary of editing repeats [N]
264 | . last edit (magic dot)
265 | :& last substitute
266 | :%& last substitute every line
267 | :%&gic last substitute every line confirm
268 | g% normal mode repeat last substitute
269 | g& last substitute on all lines
270 | @@ last recording
271 | @: last command-mode command
272 | :!! last :! command
273 | :~ last substitute
274 | :help repeating
275 | ----------------------------------------
276 | " Summary of repeated searches
277 | ; last f, t, F or T
278 | , last f, t, F or T in opposite direction
279 | n last / or ? search
280 | N last / or ? search in opposite direction
281 | ----------------------------------------
282 | " *vimtips-absolutely-essential*
283 | ----------------------------------------
284 | * # g* g# : find word under cursor () (forwards/backwards)
285 | % : match brackets {}[]()
286 | . : repeat last modification
287 | @: : repeat last : command (then @@)
288 | matchit.vim : % now matches tags