Preventing vim script from being applied to itself - vim

I have a vim script with substitutions:
:%s/|I\(cc\|ee\|CC\|EE\)|/|$I_{\1}$|/
:%s/|UOmax\([+-]\)|/|$U_{Omax\1}$|/
:%s/|KcmR|/|$K_{cmR}$|/
:%s/|KsvR|/|$K_{svR}$|/
:%s/Uoffset/$U_{offset}$/
..............
Sometimes I forget that this script is currently edited, so I execute so ~/.vim/macros/script.vim and it is modifying itself. How to make script know that it is currently edited?

You could check that expand('%:p') != expand('<sfile>:p') before continuing.
Honestly, I'm not sure I'd bother with that as undo will quickly fix the issue, and moreover as I often open many buffers, I'm likely make the mistake on any buffer.
BTW, another approach would be to define a tex ftplugin, where you'd define a fucntion that does the substitutions, and a buffer-local mapping that executes the function on the current buffer. This way, you won't have the possibility to run the substitution on buffers that are not LaTeX ones.

Try to install vim-quickrun and type <leader>r. vim-quickrun run the script from buffer instead of file if it's modified.

Related

How to save buffer (preferably if changed) and then close the buffer but not VIM?

So, I just realized I could use marks with capital letters to go to different files. That's great! However, I'm trying to find a way to close the buffer and return to the previous one. Say I go to my header file to change or add the declaration of the function I'm writing, and then I'd like to save the file, but only if there's changes to it, to go back to working on the contents of the function. How can I do this?
There's :x, but it also quits VIM
There's :bd!, but it doesnt save the changes
There's :bw, but that's even worse (unfortunately that's w[ipeout], not w[rite]...)
There's ctrl+O, but it doesnt seem to work when I edit the file (also, it doesnt actually close the buffer)
There's :up followed by :bd, but that's two commands and VIM's about efficiency, so I'd prefer a single command if it exists
There's a few other options and variants, but none that do what I wanted, afaik
It feels like this should be simple enough to do with one command, preferably without macros/plugins/functions/snippets/etc; as close to vanilla as possible. I get the feeling I'm missing something obvious.
You could concatenate commands like so:
:w|bd
I'd like to save the file, but only if there's changes to it
:up[date]
to go back to working on the contents of the function
Press Ctrl^, or enter the command :e[dit] #
I'd prefer a single command if it exists
Set an option :set autowrite and then Vim will save the current buffer on pressing Ctrl^ automatically.

Vim long file paths break/split over multiple lines in quickfix window

A long file paths is broken up over multiple lines in the Vim quickfix window which then for example does not allow to jump to the error location displayed in the qf.
The file (and the lines around) are diplayed in the quickfix window as (the example is the output from neomakes pdflatex)
|| Enter file name:
|| /long/path/to/file/.../loca
tionOfTexFiles/myTexFile.tex|144 error| Emergency stop.
|| read
to be able to follow to the file line by lnext/cnext I should have
/long/path/to/file/.../locationOfTexFiles/myTexFile.tex|144 error| Emergency stop.
For quickfix files I have the following relevant (in my view) settings which are set to:
setlocal nolinebreak
setlocal nowrap
setlocal textwidth=9999
So I am wondering how I can display the file path in one line within the quickfix window?
On :make, Vim invokes 'makeprg', captures the output, and then parses it according to 'errorformat'. The latter does support multi-line error messages (cp. :help errorformat-multi-line), but that is mostly for what I would call intentional linebreaks, as specified by the compiler. What you suffer from is unintentional linebreaks because of line wrapping (due to overly long paths).
Now, I don't know about "neomakes pdflatex", but it looks like that tool creates the linebreaks, whereas it shouldn't, as Vim is capturing the output, and there's no receiving terminal (or user). Investigating in that direction (or opening an issue at the project's tracker) might be helpful.
The mentioned Vim options ('linebreak', 'wrap', etc.) have nothing to do with it. They apply to normal buffers; the quickfix buffer as such is not modifiable.
Workarounds
A possible workaround might be to :cd first to a directory that is "closer" to the processed files (or even :set autochdir); this might avoid the long paths in the output.
Alternatively, you may "unmangle" the output by adding a sed stage after the compiler:
let &makeprg .= "| sed -e 's/.../...'"
If I'm not mistaken, the issue is on pdflatex side. The || mark is a good indication: you'll have one per output line -- in case filename and/or lines numbers are recognized, they'll be fed in between the bars.
So. This means you'll need a way to fix the path names. It'll be better to do it outside vim. I'm not saying this is trivial. I'm just saying that if you can have a program able to fix pdflatex outputs, you'll just be one pipe away from the solution (plus a correct forwarding of error codes...).
If you prefer to implement it in vim script, this is possible. But you'll experience side-effects. In my BuildToolsWrapper plugin I'm able to post-process compilation output in vim side, but the result is far from being perfect. I'm working on getqflist() result, and parse each line. When I found a line where I want to fix the filename, it's not simply about fixing the filename but also about assigning a valid buffer number to it. See this function where I can replace a filename with another one. The magic happens where lh#buffer#get_nr() is used. Still you'd need to implement a vim script able to merge split filenames.
IOW: my understanding is that vim is not involved. It could be used to fix the issue, but IMO this is not the easier path to undertake.

How to execute a command in a buffer with a specific name in the background?

I'm currently doing the following, but it makes the current window switch to the buffer in question, which is disruptive:
let current_buffer = bufname("%")
buffer NERD_tree_1
normal R
exec "buffer" current_buffer
Is there a way to execute a command in a buffer with a specific name (in this case NERD_tree_1) in the background?
No, there's no such mechanism, especially not for :normal, which executes commands in the current window.
I see two options:
Since you're already relying on plugin internals (the NERD_tree_1 buffer name), you could further delve into the plugin and directly modify it / its data structures to achieve your goal. Note that this is a brittle solution that is susceptible to future plugin updates, and therefore not recommended.
Completely rely on the plugin's external interface (i.e. replace the :buffer commands with :NERDTreeToggle), and live with the side effects of the plugin briefly activating.

Prevent gVim from returning control to command line (when called from Stata)

When I call gVim from Stata with shell (or equivalently with !) Stata doesn't wait for the command to finish and continues on with the .do file. I usually specify a short sleep and everything works great (discussed on the Stata mailing list here).
But sometimes the gVim call is lengthy and the length is unknown a priori. For example. I use gVim's argdo to remove headers from a folder of text files.
!gvim -c "argdo 1,3d | update" *sheet*.txt
Is there any way that I can force gVim to not return control to Stata? Or are my best options to complete this step outside the .do file or with a pause/lengthy sleep? Thanks!
Oh, I'm on Win 8 (64 bit) with gVim 7.3.
I think you would need to make this call a Stata command or the equivalent thereof.
That is, try running this separately from a do-file editor window or as wrapped up in a separate do-file.
I realise that is not an attractive solution, but in principle it seems the only one.
(sleep solutions I dislike as fudges, but I guess no one likes them on principle.)

Use Vim to "colourize" files or input streams

This may be an odd question, but still. I use cat to display a file in bash (KDE Konsole),
cat foobar.rb
Now, I would like to use Vim to colourize that foobar.rb file according to what you would get when you start foobar.rb in Vim. Edit: But only for display purpose, on the terminal.
I am not sure this is possible, but I thought it would be neat if I could use Vim for that.
I really just want colourized keywords, and Vim has the perfect colour definitions.
So I thought combining this would be great.
Is this possible in Vim out of the box though?
One approach would be to use a library such as Pygments, which is a general purpose syntax highlighter. You could write a wrapper called ccat or something that would apply syntax highlighting to an input file and write to stdout.
If you want to page up and down in a highlighted file, you can use less with the -R switch, which passes control characters through to the terminal directly, preserving colours. So:
ccat file.rb | less -R
But at that point, you're pretty much at the capabilities of view.
I'm not sure if I understand your question correctly, but if you are only looking for a command that will give you a read-only view of the input file (like cat) but with coloured keywords, use view. view is an alternative way to start vim in read-only mode, so you have all syntax highlighting possibilities. From the vim man page:
view Start in read-only mode. You will be protected from writing
the files. Can also be done with the "-R" argument.
gvim gview
The GUI version. Starts a new window. Can also be done with
the "-g" argument.
evim eview
The GUI version in easy mode. Starts a new window. Can also
be done with the "-y" argument.
rvim rview rgvim rgview
Like the above, but with restrictions. It will not be possi-
ble to start shell commands, or suspend Vim. Can also be
done with the "-Z" argument.
I have always seen view on systems that have vim installed.
Closest is the less script that comes with vim:
cat myfile | vim -u /usr/share/vim/vim72/macros/less.vim -
Note the - argument to vim. You may need to change the vim72 to your version (and the whole path if you have it installed elsewhere)
Now, this isn't exactly what you want, because its behaviour is less-like, in that you have to press keys to make it scroll down or complete. However, they are briefer than usual vim. For example, space to scroll down; and q to quit (not :q).
You want a cat-like version; me too. But there doesn't seem to be one.
EDIT uh, there's also a vimpager project, that includes vimcat - exactly what you want. But it doesn't come with vim, and I haven't tried it yet.
vim.org: http://www.vim.org/scripts/script.php?script_id=1723
github: https://github.com/rkitover/vimpager

Resources