Does less have an equivalent to vim's scrolloff? - less-unix

I have scrolloff set to 4 in vim. This means that when I scroll up or down, there are 4 lines between the line I'm on and the bottom or top of the screen.
When I use less, usually to view a manpage, I use / to search for text. If I'm looking for a command line option that does something and I search for the term 'something' usually 'something' shows up in the paragraph explaining a command, and the command line switch is a line or two above that, so I have to scroll up to see it. Any ideas for how to make less act more like vim in this one case?

I believe you want the -j option. It doesn't seem to have a bottom-or-top mode, but rather a bottom-mode or top-mode. For instance:
less -j 4
Will always display your search term on the 4th line (from the top), whereas
less -j -4
Will always display your search term on the 4th line from the bottom.
And of course, you can use alias to make your preference the default, by adding this to your .bashrc, for instance:
alias less="less -j 4"

Not sure if you can make less do this by itself, but did you know you can use Vim in place of less as your pager? There's a macro in the Vim installation macros/ directory called less.vim. Copy it to your own .vim/macros directory to enable, then alias less in your .bashrc (or whatever your shell)
# example:
alias less='/usr/share/vim/7.x/macro/less.sh'
EDIT Unfortunately I just tried this myself and it ignores the scrolloff by default. You could modify the less.sh to set scrolloff=3 at launch.

Related

Move to specific line and column in one command

Let's say we have a text file that is very long and has many lines. I want to move to 30th line and 15th column in this file.
Are there any VIM commands that could be used to move to mentioned line number and column in one command? Thanks.
Please, do not suggest to use smt like :30 command and after 15| this is NOT an option.
May VIM has an option to input smt like: :30,15, just in another syntax?
The only option I found is to use :call cursor(30,15) but it looks little bit too long, as I need to type it each time I want to jump to the another position.
You can define your own command-line command. Define it in ~/.vimrc and it will be available everywhere. Define:
:command -nargs=* Go call cursor(<f-args>)
Run:
:Go 30 15
Well, you want to move across two dimensions but Vim commands are limited to one dimension, therefore you can't move to line 30 and column 15 with a single built-in command.
Here are the shortest key sequences to move to column 15 of line 30:
" in normal mode
30G15|
" in command-line mode and normal mode
:30<CR>15|<CR>
" in command-line mode
:30norm15|<CR>
" from the shell
$ vim foo.txt +norm30G15\|<CR>
Note that the first suggestion above is already the shortest theoretically possible sequence because you would need:
at least one key for the command itself,
at least one key to separate the two coordinates,
the vertical coordinate (can't be shortened),
and the horizontal coordinate (can't be shortened).
The only improvement I can think of to 30G15| would be to use keys that don't require a modifier but, frankly, I am not sure that it is worth the hassle.

Is it possible to take control of sublimetext3 tabs with cmd

Good Day.
I am a hobby programmer, and am just looking for creative ways to get things done.
In particular, closing a tab or tabs in sublimetext3 through a cmd line method.
The even cooler thing would be, if so, is there a way to decide in cmd which tab to close e.g. 3rd from left/right etc?
In keeping with the idea that this is mostly curiosity and preference than anything else, so creative replies are definitely appreciated as well.
You can execute any command* from the command line, so this is very much possible.
For example, to close the active tab of the most recently used Sublime Text window, you can run subl --command close.
To close a specific tab, for example the 18th tab, which will have index 17 because it is zero-based:
subl --command 'close_by_index {"group": 0, "index": 17}'
(This is assuming bash syntax - for Windows cmd syntax, you may need to do some creative escaping because the command arguments have to be valid JSON and quoted as part of the same argument as the name of the command you want to execute.)
This is exactly the same command that would be run when right-clicking on the tab and picking Close Tab in the context menu. This command can be seen by inspecting Packages/Default/Tab Context.sublime-menu using the built-in View Package File functionality in the Command Palette. You can check this file to see other pre-defined entries like closing all other tabs, or tabs to the right etc.
*: Caveats being if ST is not already running, then it tries to run the command before plugins are loaded.

Scrolling "too long" command doesn't work properly

Assume I want to invoke a tool with a lot of options, like:
$ somescript --option1 --option2 --option3 --option4 --option5 whatever even more stuff
But the width of the terminal doesn't allow to have that thing on a "single line".
That alone isn't a problem, but with fish, there is a problem with scrolling.
When I enter that extra-wide command, at some point, there will be a line break:
$ somescript --option1 --option2 --option3 --option4 --option5
whatever even more stuff
All fine so far. While typing such a lengthy command, I can scroll forth and back at any point. Works as expected. So, assume I entered the command, made a mistake, and now want to remove --option4.
The normal thing: use "arrow up" to get to that command in the history, to then use "arrow left" to scroll within the command. And now something weird happens.
Everything is fine while the cursor is within the second line. But when the cursor moves to the first line ... after 3 to 5 more "arrow left" strokes, the cursor moves UP another line. Then it sits above the first line of the command. There is also a vertical jump of a few characters.
In other words: as soon as a command is longer than the width of the terminal, I am unable to scroll into the first line reliably. The cursor shows up somewhere, and it is really hard to guess where it really sits at any moment. Which makes it almost impossible to edit anything in that first line.
This is on MacOs, using iterm 3.2.9 and fish version 3.0.2 installed via brew.
Wrote up defect 6014 on github. Outcome is rather frustrating.
The problem is: the Mac terminal(s) all handle certain unicode characters the wrong way. "Normally" that isn't a problem, but when you use one of those fish prompts that give you the git status (like AcidHub which is my favorite) ... fish can't compute/determine the exact line width, and there you go.
So, basically, when using fish on MacOs, option space is limited to:
use the defaults, which (when using special prompts, like AcidHub will lead to scrolling issues)
adapt the fish prompt accordingly (in my case, I replaced all special unicode chars with something simpler). It doesn't look that great, but scrolling simply works again.
And a completely different and unexpected solution to the problem: I am using iterm2 on my Mac, and iterm2 just added a "status bar" section. That can be easily configured, and of course, it already has a status bar component that tells you about git status.
Thus my solution: I changed the fish prompt to just give the PWD, and all the other things that the AcidHub prompt has to offer, are now "iterm2 status bar" components!

Stop emacs from wrapping 80 column lines in an 80 column terminal?

In an 80 column wide terminal emacs wraps 80 column lines, putting a backslash in the 80th column. Is there a way to tell emacs to use all 80 columns of my terminal and not wrap lines until they reach 81 characters?
If I understand this question correctly, this is not about logical line
wrapping (how lines are segmented in your file), but about visual wrapping
(how lines are displayed with respect to window width).
If you just want the display to visually wrap more than zero characters before
window boundary, and thus avoid the backslash everywhere, however long your logical lines really are, you can use longlines-mode
:
Unlike Visual Line mode, Long Lines mode breaks long lines at the fill column (see Fill Commands), rather than the right window edge. To enable Long Lines mode, type M-x longlines-mode. If the text is full of long lines, this also immediately “wraps” them all.
Then, it's only a matter of setting the fill-column appropriately, using
either global settings (.emacs, though you probably want to use a
specific mode-hook for that particular case), local settings (file
variable, dir-locals) or C-u 79 C-uC-x
f to set variable fill-column to 79. This way, lines 79
characters or higher will wrap, but before touching the right edge of the
80-char window (and thus never leaving an ugly backslash character). Your
file will be untouched.
If you simply want no visual wrapping to occur on 80-character lines, and thus do not want the 80th logical character visually displayed below the first, there are two
possible answers:
either you work in an environment where you don't necessarily wrap
logically at or before 80 characters, and you want to see the end of
those 81+ lines somewhere in your screen (i.e. you do want visual wrap, but at a number of chars above the window width), then I don't know how to do
it.
or you want to stop your lines at 80 chars logically (e.g. you
have auto-fill on and fill-column at 80), and if you do happen to have
lines 81 characters or more, you don't care about seeing their ending.
In that case, activate truncate-mode (toggle-truncate-lines).
If the issue is about the last character of your window, and what you really want is the 80th logical character of your line to be displayed on the 80th visual character of your window, though, I'm afraid I don't know how. Either you are truncating lines (as above), and the last character of your window will be a $, or you let emacs do its thing, and the last character will be a backslash.
Note when testing that auto-fill's wrapping (but also longlines-mode's, since it is its visual equivalent) will occur only at word boundaries.
One option is to set the wrapping to happen at 81, instead of 80.
M-x set-fill-column RET 81
Another option, maybe the best choice, is to define the variable overflow-newline-into-fringe as t. Try this once, manually:
M-x set-variable RET overflow-newline-into-fringe RET t
Either of these could be set by default. You can do that through M-x customize or by editing your .emacs file. Post again if you need help.
BTW, do you use emacs in a graphical or terminal environment? In a graphical environment, I often just make the window larger if I have long lines. Or I may turn on line truncation with a horizontal scrollbar.
added later
With the added information that you are running emacs in terminal mode, as you discovered, none of those options work. I tried an example running emacs in putty, where I can change the size of the window and emacs picks it right up. So, I could size to 81 columns and my 80-column lines remain intact without continuation. I am not sure which TERM value you have assigned with tmux, but you could consider creating a custom terminal type (termcap or terminfo) which supports 81 columns. I only took a brief glance at tmux but I noticed that you can resize panes within a terminal.
Now, out of curiosity, what is the primary motivator for you using tmux? I would think that the resume capability would be valuable. I would find however, that the other features are not that useful because in an X-Window environment it is cheap & easy to open more terminals or if I am using putty, I can create more of those. As far as using emacs, whether I am running under X-Window or MS-Windows, I just create as many frames as I would like and can work quite easily with that. So, is there something else that makes you interested in using tmux?
Six years after the previous answers and the workaround I still use is to use 81 character-wide windows.
Unfortunately 80-wide windows that wrap 'correctly' are not possible because of evil fringe characters. Emacs requires the last (fringe) character to have exclusive use of the final column. The argument for this is an optional fringe character is ambiguous. I dream of the day someone will submit a patch to make the fringe character optional, and perhaps solving the ambiguity with a background color.
I don't think that is prossible in general, because emacs needs at least one character to indicate that the line continues in the next line (wraps), although I'm not sure, because emacs has so many options... You could maybe instead select "Word Wrap (Visual Line Mode)" in the "Options" menu (or keyboard):
M-x visual-line-modeRET
This makes the flow more natural, without showing (at least in text modes) the indication of wrapping.

How can I script vim to run perltidy on a buffer?

At my current job, we have coding-style standards that are different from the ones I normally follow. Fortunately, we have a canned RC file for perltidy that I can apply to reformat files before I submit them to our review process.
I have code for emacs that I use to run a command over a buffer and replace the buffer with the output, which I have adapted for this. But I sometimes alternate between emacs and vim, and would like to have the same capabilities there. I'm sure that this or something similar is simple and had been done and re-done many times over. But I've not had much luck finding any examples of vim-script that seem to do what I need. Which is, in essence, to be able to hit a key combo (like Ctrl-F6, what I use in emacs) and have the buffer be reformatted in-place by perltidy. While I'm a comfortable vim-user, I'm completely clueless at writing this sort of thing for vim.
After trying #hobbs answer I noticed that when filtering the entire buffer through perltidy the cursor returned to byte 1, and I had to make a mental note of the original line number so I could go back after :Tidy completed.
So building on #hobbs' and #Ignacio's answers, I added the following to my .vimrc:
"define :Tidy command to run perltidy on visual selection || entire buffer"
command -range=% -nargs=* Tidy <line1>,<line2>!perltidy
"run :Tidy on entire buffer and return cursor to (approximate) original position"
fun DoTidy()
let l = line(".")
let c = col(".")
:Tidy
call cursor(l, c)
endfun
"shortcut for normal mode to run on entire buffer then return to current line"
au Filetype perl nmap <F2> :call DoTidy()<CR>
"shortcut for visual mode to run on the current visual selection"
au Filetype perl vmap <F2> :Tidy<CR>
(closing " added to comments for SO syntax highlighting purposes (not required, but valid vim syntax))
DoTidy() will return the cursor to its original position plus or minus at most X bytes, where X is the number of bytes added/removed by perltidy relative to the original cursor position. But this is fairly trivial as long as you keep things tidy :).
[Vim version: 7.2]
EDIT: Updated DoTidy() to incorporate #mikew's comment for readability and for compatibility with Vim 7.0
My tidy command:
command -range=% -nargs=* Tidy <line1>,<line2>!
\perltidy (your default options go here) <args>
If you use a visual selection or provide a range then it will tidy the selected range, otherwise it will use the whole file. You can put a set of default options (if you have any) at the point where I wrote (your default options go here), but any arguments that you provide to :Tidy will be appended to the perltidy commandline, overriding your defaults. (If you use a .perltidyrc you might not have default args -- that's fine -- but then again you might want to have a default like --profile=vim that sets up defaults only for when you're working in vim. Whatever works.)
The command to filter the entire buffer through an external program is:
:%!command
Put the following in ~/.vimrc to bind it to Ctrl-F6 in normal mode:
:nmap <C-F6> :%!command<CR>
For added fun:
:au Filetype perl nmap <C-F6> :%!command<CR>
This will only map the filter if editing a Perl file.
Taking hobbs' answer a step further, you can map that command to a shortcut key:
command -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
noremap <C-F6> :Tidy<CR>
And another step further: Only map the command when you're in a Perl buffer (since you probably wouldn't want to run perltidy on any other language):
autocmd BufRead,BufNewFile *.pl,*.plx,*.pm command! -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
autocmd BufRead,BufNewFile *.pl,*.plx,*.pm noremap <C-F6> :Tidy<CR>
Now you can press Ctrl-F6 without an active selection to format the whole file, or with an active selection to format just that section.
Instead of creating a new keyboard shortcut, how about replacing the meaning of the = command which is already in people's finger memory for indenting stuff? Yes, perlcritic does more than just indent but when you use perlcritic anyways, then you probably don't want to go back to the inferior "just indent" = command. So lets overwrite it!
filetype plugin indent on
autocmd FileType perl setlocal equalprg=perltidy
And now we can use = just like before but with the added functionality of perlcritic that goes beyond just indenting lines:
== run perlcritic on the current line
5== run perlcritic on five lines
=i{ Re-indent the 'inner block', i.e. the contents of the block
=a{ Re-indent 'a block', i.e. block and containing braces
=2a{ Re-indent '2 blocks', i.e. this block and containing block
gg=G run perlcritic on the entire buffer
And the best part is, that you don't have to learn any new shortcuts but can continue using the ones you already used with more power. :)
I'm used to select text using line oriented visual Shift+V and then I press : an I have !perltidy -pbp -et4 somewhere in history so I hit once or more up arrow ⇧.