Is it possible to reopen closed window in vim, that was in split?
Something like ctrl+shift+t with browser tabs?
:vs# will split current window vertically and open the alternate file.
It's so simple that you don't need to bind it to key.
Nice question! I was thinking to something like the following:
nmap <c-s-t> :vs<bar>:b#<CR>
It should work as you want.
No need for SHIFT:
nmap <c-t> :vs<bar>:b#<CR>
In conjunction with CTRL the characters are handled equally by vim, capitalized or not.
Actually also in the answer before, CTRLn and CTRLSHIFTN should both work.
I've gotten this to work by using bufmru.vim!
The following command, :ReopenLastTab, will re-split the last-open buffer:
command ReopenLastTab execute "vsplit" bufname(g:bufmru_bnrs[1])
I installed bufmru using Vundle, as below, but of course you can install it any way you like.
#.vimrc
" Install bufmru with Vundle
Plugin 'vim-scripts/bufmru.vim'
let g:bufmru_switchkey = "<c-t>" " I never use this: the default is Space, but I don't need to use it so set it to something I don't care about.
If anyone need something more generic I made this function.
Just place it in your .vimrc
" open last closed buffer
function! OpenLastClosed()
let last_buf = bufname('#')
if empty(last_buf)
echo "No recently closed buffer found"
return
endif
let result = input("Open ". last_buf . " in (n)ormal (v)split, (t)ab or (s)plit ? (n/v/t/s) : ")
if empty(result) || (result !=# 'v' && result !=# 't' && result !=# 's' && result !=# 'n')
return
endif
if result ==# 't'
execute 'tabnew'
elseif result ==# 'v'
execute "vsplit"
elseif result ==# 's'
execute "split"
endif
execute 'b ' . last_buf
endfunction
nnoremap <C-t> :call OpenLastClosed() <CR>
Call it with Ctrl+t and then select where you want to open that file.
Related
Is there a way to run the script as if it were typed into the interpeter? The benefits are that I don't need echos everywhere, the work done is saved as a file, and I can use vim to do the editing. Example:
example.ijs
x =. 1
x + 3
terminal
x =. 1
x + 3
4
If not, I'll write a vimscript that can do the above then share them here. The advantage of a vimscript solution is that I could have commands to run the entire file, the current line, the current selection, everything up to and including the current line, or whatever else is useful.
Related but not a duplicate: How to call J (ijconsole) with a script automatically
It sounds like you are asking for this to be solved for the jconsole interface. I don't have answer for that, but would point out that that functionality is available for both the JHS and jQt interfaces. If you don't mind switching to a different interface then that would be a quick and easy solution.
The easiest way to interactively run a script is to use labs command:
load'labs/lab'
lab'myscript.ijt'
1 of 2 in myscript.ijt
x =. 1
NB. press Ctrl+'.' to advance.
x + 3
4
NB. Run the whole script.
lab 1 _
x =. 1
x + 3
4
More info about labs here
If you want to non-interactively run a script as if typed in the console, you can just feed the script to j (in linux):
j < myscript.ijs
4
Alternatively, to
see the lines on the screen just as though they had been typed from the keyboard
from a script, you can use 0!:1:
0!:1 < 'myscript.ijs'
x =. 1
x + 3
4
Use loadd rather than load to run the script and display the lines and results.
loadd 'example.ijs'
x =. 1
x + 3
4
This is the vimscript solution I mentioned. It's as far as I can tell language agnostic as well.
" Global variable dictates whether new terminals are opened
" horizontally ('h') or vertically ('v').
let g:terminalsplit = 'h'
" Add execution strings for each language you use.
augroup terminalcommands
autocmd!
autocmd Filetype j let g:cmdstr = 'jconsole.cmd'
autocmd Filetype python let g:cmdstr = 'python'
augroup END
" Close all terminals
nnoremap <silent> <leader>p :call CloseTerminal()<cr>
" Run file
nnoremap <leader>h :call Run(g:cmdstr, 'script')<cr>
" Run as if file were entered line-by-line into the interpreter
" Mappings for: Line, selection, file up to line, entire file
nnoremap <leader>j yy:call Run(g:cmdstr, 'interpreter')<cr>
vnoremap <leader>j ygv<esc>:call Run(g:cmdstr, 'interpreter')<cr>
nnoremap <leader>k Vggy<c-O>:call Run(g:cmdstr, 'interpreter')<cr>
nnoremap <leader>l mzggVGy'z:call Run(g:cmdstr, 'interpreter')<cr>
function! Run(cmdstr, mode)
let filepath = expand('%:p') " Copy filepath before switch to terminal
call CloseTerminal()
call OpenTerminal()
echo g:clear . " & " . a:cmdstr
call feedkeys(g:clear . " & " . a:cmdstr) " Begin run command
call RunCode(filepath, a:mode)
call feedkeys("\<c-w>p") " Switch back to file window
endfunction
function! CloseTerminal()
if has('nvim')
let terminals = split(execute('filter/term:/ls'), '\n')
else
let terminals = split(execute('filter/!/ls'), '\n')
endif
for i in range(len(terminals))
silent! exe "bd! " . split(terminals[i], ' ')[0]
endfor
endfunction
function! OpenTerminal()
if g:terminalsplit == 'h'
terminal
elseif g:terminalsplit == 'v'
vertical terminal
else
echo 'g:terminalsplit=' . &g:terminalsplit . '. Must be "h" or "v".'
endif
endfunction
function! RunCode(filepath, mode)
if a:mode == 'script'
call feedkeys(" " . a:filepath . "\<cr>")
elseif a:mode == 'interpreter'
call feedkeys("\<cr>")
call feedkeys("\<c-w>\"\"")
else
echo 'a:mode=' . a:mode . '. Must be "script" or "interpreter".'
endif
endfunction
" Use to clear the terminal window before running the script
if has('unix')
let g:clear = 'clear'
else
let g:clear = 'cls'
endif
I know my question title is not explanatory enough so let me try to explain.
I created a vim function that displays my current battery state. My function is as follows:
function! BatteryStatus()
let l:status = system("~/battery_status.sh")
echo join(split(l:status))
endfunction
I have mapped the above function as nnoremap <F3> :call BatteryStatus()<cr>. Now, when I press F3 it displays my battery status as Discharging, 56%, 05:01:42 remaining which is my required output but my question is how do I make the above output disappear.
Currently what happens is after function call it continuously displays the output and I have to manually use :echo to clear the command window(:).
So, what necessary changes are to be made in my function so that I can achieve toggle like behaviour.
battery_status.sh
acpi | awk -F ": " '{print $2}'
PS: This is part of a learning exercise. So, please don't suggest alternative vim scripts.
Simplistic straightforward way to toggling the output:
let s:battery_status_output_flag = "show"
function! BatteryStatus()
if s:battery_status_output_flag == "show"
let l:status = system("~/battery_status.sh")
echo join(split(l:status))
let s:battery_status_output_flag = "clear"
else
echo ""
let s:battery_status_output_flag = "show"
endif
endfunction
Note s: prefix, see :help script-variable
You can define a autocmd:
:au CursorHold * redraw!
Vim redraws itself 4 sec (set by updatetime option) after it's idle.
vim
function! pseudocl#render#clear()
echon "\r\r"
echon ''
endfunction
You can just Ctrl+ L to clear the message on the status
line.
Is it possible to reopen closed window in vim, that was in split?
Something like ctrl+shift+t with browser tabs?
:vs# will split current window vertically and open the alternate file.
It's so simple that you don't need to bind it to key.
Nice question! I was thinking to something like the following:
nmap <c-s-t> :vs<bar>:b#<CR>
It should work as you want.
No need for SHIFT:
nmap <c-t> :vs<bar>:b#<CR>
In conjunction with CTRL the characters are handled equally by vim, capitalized or not.
Actually also in the answer before, CTRLn and CTRLSHIFTN should both work.
I've gotten this to work by using bufmru.vim!
The following command, :ReopenLastTab, will re-split the last-open buffer:
command ReopenLastTab execute "vsplit" bufname(g:bufmru_bnrs[1])
I installed bufmru using Vundle, as below, but of course you can install it any way you like.
#.vimrc
" Install bufmru with Vundle
Plugin 'vim-scripts/bufmru.vim'
let g:bufmru_switchkey = "<c-t>" " I never use this: the default is Space, but I don't need to use it so set it to something I don't care about.
If anyone need something more generic I made this function.
Just place it in your .vimrc
" open last closed buffer
function! OpenLastClosed()
let last_buf = bufname('#')
if empty(last_buf)
echo "No recently closed buffer found"
return
endif
let result = input("Open ". last_buf . " in (n)ormal (v)split, (t)ab or (s)plit ? (n/v/t/s) : ")
if empty(result) || (result !=# 'v' && result !=# 't' && result !=# 's' && result !=# 'n')
return
endif
if result ==# 't'
execute 'tabnew'
elseif result ==# 'v'
execute "vsplit"
elseif result ==# 's'
execute "split"
endif
execute 'b ' . last_buf
endfunction
nnoremap <C-t> :call OpenLastClosed() <CR>
Call it with Ctrl+t and then select where you want to open that file.
Suppose that I have a document like this, and I want to search for all occurences of the URL:
Vim resources: [http://example.com/search?q=vim][q]
...
[q]: http://example.com/search?q=vim
I don't want to type it out in full, so I'll place my cursor on the first URL, and run "uyi[ to yank it into the 'u' register. Now to search for it, I'd like to just paste the contents of that register into the search field by running:
/\V<c-r>u<CR>
This results in Vim searching for the string 'http:' - because the '/' character terminates the search field.
I can get around the problem by running this instead:
/\V<c-r>=escape(#u, '\/')<CR><CR>
But it's a lot of typing!
How can I create a mapping for Vim's commandline that simplifies this workflow?
My ideal workflow would go something like this:
press /\V to bring up the search prompt, and use very nomagic mode
hit ctrl-x to trigger the custom mapping (ctrl-x is available)
Vim listens for the next key press... (pressing <Esc> would cancel)
pressing 'u' would escape the contents of the 'u' register, and insert on the command line
Try this:
cnoremap <c-x> <c-r>=<SID>PasteEscaped()<cr>
function! s:PasteEscaped()
" show some kind of feedback
echo ":".getcmdline()."..."
" get a character from the user
let char = getchar()
if char == "\<esc>"
return ''
else
let register_content = getreg(nr2char(char))
return escape(register_content, '\/')
endif
endfunction
By the way, something that might be useful to know (if you don't already) is that you can use ? as the delimiter for :s. Which means that you could write a search-and-replace for an url like so:
:s?http://foo.com?http://bar.com?g
I've accepted Andrew Radev's solution, which solved the hard parts. But here's the version that I've added to my vimrc file, which adds a couple of enhancements:
cnoremap <c-x> <c-r>=<SID>PasteEscaped()<cr>
function! s:PasteEscaped()
echo "\\".getcmdline()."\""
let char = getchar()
if char == "\<esc>"
return ''
else
let register_content = getreg(nr2char(char))
let escaped_register = escape(register_content, '\'.getcmdtype())
return substitute(escaped_register, '\n', '\\n', 'g')
endif
endfunction
This should work:
whether you use / or ? (to search forwards, or backwards)
and when the pasted register includes multiple lines
Also, I changed the prompt. While waiting for a register, the prompt switches to \ - which seems like a suitable cue for 'PasteEscaped'. Also, I've appended a ", which mimics Vim's behavior after pressing <c-r> at the command line.
If you've any further suggestions for improvements, please leave a comment.
How about different workflow? For example, creating your own operator to search target text as is:
" https://gist.github.com/1213642
" Requiement: https://github.com/kana/vim-operator-user
map YourFavoriteKeySequence <Plug>(operator-search-target-text)
call operator#user#define('search-target-text', 'OperatorSerachTargetText')
function! OperatorSerachTargetText(motion_wise)
execute 'normal!' '`['.operator#user#visual_command_from_wise_name(a:motion_wise).'`]"xy'
let #/ = '\V' . escape(substitute(#x, '[\r\n]$', '', ''), '\')
normal! n
endfunction
I like #nelstrom's solution and made a small change to support escaping [ and ].
cnoremap <c-x> <c-r>=<SID>PasteEscaped()<cr>
function! s:PasteEscaped()
echo "\\".getcmdline()."\""
let char = getchar()
if char == "\<esc>"
return ''
else
let register_content = getreg(nr2char(char))
let escaped_register = escape(register_content, '\'.getcmdtype())
let escaped_register2 = substitute(escaped_register,'[','\\[','g')
let escaped_register3 = substitute(escaped_register2,']','\\]','g')
return substitute(escaped_register3, '\n', '\\n', 'g')
endif
endfunction
I want vim to open up the :Explorer when no file is opened or created. Eg. when I call vim without any options.
calling vim newfile.txt should still behave the normal way though.
How would I go about doing this? I can't seem to find the correct autocmd for it.
If you want to do this for vim invocation only, the best way is to use argc():
autocmd VimEnter * :if argc() is 0 | Explore | endif
argc() function returns a number of filenames specified on command-line when vim was invoked unless something modified arguments list, more information at :h argc().
Found the answer myself:
"open to Explorer when no file is opened
function! TabIsEmpty()
" Remember which window we're in at the moment
let initial_win_num = winnr()
let win_count = 0
" Add the length of the file name on to count:
" this will be 0 if there is no file name
windo let win_count += len(expand('%'))
" Go back to the initial window
exe initial_win_num . "wincmd w"
" Check count
if win_count == 0
" Tab page is empty
return 1
else
return 0
endif
endfunction
" Test it like this:
" echo TabIsEmpty()
function! OpenExplorer()
if (TabIsEmpty())
:Explore
end
endfunction
The greatest part of this code was taken from this question.