mapping the shift key in vim - coffeescript

I'm having an issue when mapping the Shift key in VIM. I want Ctrl+L to behave differently than Ctrl+Shift+L
so I have this
" for insert mode remap <c-l> to:
" Insert a hash rocket for ruby
" Insert a -> for php
" for coffee the shift key decides
function! SmartHash(...)
let shift = a:0 > 0
let ruby = &ft == 'ruby'
let php = &ft == 'php'
let coffee = &ft == 'coffee'
if php
return "\->"
end
if coffee
return shift ? "\ =>\n" : "\ ->\n"
end
if ruby
return "\ => "
end
return ""
endfunction
imap <c-l> <c-r>=SmartHash()<cr>
imap <C-S-L> <c-r>=SmartHash(1)<cr>
...but it's just triggering the second mapping whether I have the Shift key pressed or not.
Updated based on accepted answer
" for insert mode remap <c-l> to:
" Insert a hash rocket for ruby
" Insert a -> for php and coffeescript
" double tapping does alternate symbol for php and coffescript
function! SmartHash(...)
let alt = a:0 > 0
let ruby = &ft == 'ruby'
let php = &ft == 'php'
let coffee = &ft == 'coffee'
if php || coffee
return alt ? "\ =>\n" : "\ ->\n"
end
if ruby
return "\ => "
end
return ""
endfunction
imap <c-l> <c-r>=SmartHash()<cr>
imap <c-l><c-l> <c-r>=SmartHash(1)<cr>

Due to the way that the keyboard input is handled internally, this unfortunately isn't possible today, even in GVIM. This is a known pain point, and the subject of various discussions on vim_dev and the #vim IRC channel.
Some people (foremost Paul LeoNerd Evans) want to fix that (even for console Vim in terminals that support this), and have floated various proposals, cp. http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8
But as of today, no patches or volunteers have yet come forward, though many have expressed a desire to have this in a future Vim 8 major release.
I usually work around this by starting my alternate mapping with g, e.g. <C-l> and g<C-l>, but that won't work in insert mode. In your case, with a little bit of additional logic, you could make a second <C-l> at the same position change the previously inserted -> to =>, so that you get the first alternative via <C-l>, and the second via <C-l><C-l>.

Related

Autohotkey foreign language accents

I'm trying to create an easy ahk script for sending letters with accent marks when typing in different languages.
I know I can use !a::Send {U+00E0} to send à, but is there an easy way to say "If I enter a capital a, send À? I thought I'd be able to use !+a::Send {U+00C0} but that doesn't seem to work (and also seems a bit more complicated than it should be)
Eabryt,
The way I addressed this in AutoHotKey is like this:
;===== SPECIAL CHARACTERS FOR US KEYBOARD DRIVER (NOT US INTERNATIONAL) =======
:?C*:`` :: ; Turn `{Space} into a neutral `, else ` will be used in next vowel.
Send, ``{Space}{BackSpace}
Return
:?C*:``a::à
:?C*:``i::ì
:?C*:``e::è
:?C*:``o::ò
:?C*:``u::ù
:?C*:``A::À
:?C*:``I::Ì
:?C*:``E::È
:?C*:``O::Ò
:?C*:``U::Ù
:?C*:^ :: ; Turn ^{Space} into neutral ^, else ^ will be used in next vowel.
Send, {^}{Space}{BackSpace}
Return
:?C*:^a::â
:?C*:^i::î
:?C*:^e::ê
:?C*:^o::ô
:?C*:^u::û
:?C*:^A::Â
:?C*:^I::Î
:?C*:^E::Ê
:?C*:^O::Ô
:?C*:^U::Û
:?C*:`" :: ; Turn "{Space} into neutral ", else " will be used in next vowel.
Send, +{'}{Space}{BackSpace}
Return
:?C*:`'a::ä ; I used 'because I use the Umlaut's much more often than the accent aigu
:?C*:`;a::ä
:?C*:`'i::ï
:?C*:`;i::ï
:?C*:`'e::ë
:?C*:`;e::ë
:?C*:`'o::ö
:?C*:`;o::ö
:?C*:`'u::ü
:?C*:`;u::ü
:?C*:`'A::Ä
:?C*:`'I::Ï
:?C*:`'E::Ë
:?C*:`'O::Ö
:?C*:`'U::Ü
:?C*:' :: ; Turn '{Space} into neutral ', else ' will be used in next vowel.
Send, {'}{Space}{BackSpace}
Return
:?C*:`"a::á
:?C*:`"i::í
:?C*:`"e::é
:?C*:`"o::ó
:?C*:`"u::ú
:?C*:`"A::Á
:?C*:`"I::Í
:?C*:`"E::É
:?C*:`"O::Ó
:?C*:`"U::Ú
:?C*:`'c::ç
:?C*:`'C::Ç
:?C*:ss]::ß
:?C*:sss::ß
:?C*:ae]::æ
:?C*:AE]::Æ
:?C*:oe]::œ
:?C*:OE]::Œ
I use the Umlauts far more often than the accent aigu, therefore I (personally) swapped the use of the "and ' on my US International Keyboard. If this is too confusing, then just swap:
:?C*:`'a::ä with :?C*:`"a::ä
and
:?C*:`"a::á with :?C*:`'a::á
At the end are some special characters. I use the ] as the end sign for these special characters as it is close to the [Enter] key.

swapping variable name and variable type

I have a text file with a long list of variables like this:
a VARCHAR(32),
b INT,
c TINYINT,
.
.
.
I want to quickly swap the order of the name and type so I have:
VARCHAR(32) a,
INT b,
TINYINT c
.
.
.
Im happy to use a bash terminal or notepad ++ and I do have a basic knowledge of regex but Im not sure how to tackle this problem.
How can I go about doing this?
you can use this app I just wrote:
http://codepen.io/franzskuffka/pen/Ndxejz
Or run it through this function
function swap (text) {
let lines = text.split(',\n')
let parts = lines.map(function (line) {
var lineParts = line.split(' ')
lineParts[2] = lineParts[0]
delete lineParts[0]
return lineParts.join(' ')
})
return parts.join(',\n')
}
Generally I recommend the text editor Kakoune for this task which is awesome for text processing in general due to the multicursor support and incremental editing.

Getting the cursor context in Dragon NaturallySpeaking's advanced scripting

I wonder whether it is possible to get the cursor context in Dragon NaturallySpeaking's advanced scripting.
By cursor context, I mean the surrounding characters. For example, I sometimes want to condition some steps of a voice command on whether the character preceding the cursor is a space.
Best I could come up with is my CheckNewPara function shown here: http://knowbrainer.com/forums/forum/messageview.cfm?catid=4&threadid=2739&discTab=true&messid=11427&parentid=11409&FTVAR_FORUMVIEWTMP=Single
Function CheckNewPara()
Clipboard$()
SendKeys "+{Left}^c", True ' copy previous character
Select Case Clipboard$()
Case "" ' if the prior character is nothing
CheckNewPara = "" ' add no space
Case Chr(13)&Chr(10), Chr(9), ")" ' if the prior character is a Lf-CR, tab or )
SendKeys "{Right}", True
CheckNewPara = "" ' add no space
Case "." ' if the prior character is a period
SendKeys "{Right}", True
Clipboard$() ' check for No.
SendKeys "+{Left 3}^c", True ' copy prior three characters
SendKeys "{Right}", True
If Clipboard$() = "No." Then
CheckNewPara = " " ' add one space after No.
Else
CheckNewPara = " " ' add two spaces after period
End If
Case "?", "!"
SendKeys "{Right}", True
CheckNewPara = " " ' add two spaces after other ends of sentence
Case Else
SendKeys "{Right}", True
CheckNewPara = " " ' add one space in the usual case
End Select
Clipboard$()
End Function
You should look at the complete topic at http://knowbrainer.com/forums/forum/messageview.cfm?FTVAR_FORUMVIEWTMP=Linear&catid=4&threadid=2739&discTab=true to get all the context, but the code in the post I pointed to should get you started.
My newest version of the function actually calls an AutoHotKey script which looks at both the prior three characters (or as many as there are, if there are any) and the next two characters (or how ever many there are, if there are any) and returns either a space, two spaces, or nothing depending on the context. The context could be a terminal punctuation (requiring two spaces) or a pound/hash # symbol or close paren bracket or brace ) ] } all requiring no spaces, or else by default one space. I also have it so I can call it before and/or after typing in the results of a Dragon command.
HTH, YMMV,

Formula won't display when certain fields are null

Similar to my first question. I want to show my address in a text box containing the fields as follows
{Company}
{AddLine1}
{AddLine2}
{ZIP}{State}{City}
{Country}
The line that concerns me (and hopefully some of you guys) is {ZIP} {City} {State}. What I want to produce is a consistent addressing format, so that there will be no blank space or indentation even if a ZIP, City or State field has been left blank in the DB. This line should still line up with the rest of the rows and not be indented. I also wish to insert commas between zip, state, city where they are relevant and leave them out where not. For this I have written a formula. Below:
If isnull({BILL_TO.ZIP}) or trim({BILL_TO.ZIP})= "" Then "" else {BILL_TO.ZIP}
+
(If isnull({BILL_TO.State}) or trim({BILL_TO.State})= "" Then ""
else(If not isnull({BILL_TO.ZIP}) and length(trim({BILL_TO.ZIP})) <> 0 Then ", " else "") + {BILL_TO.State})
+
(If isnull({BILL_TO.CITY}) or length(trim({BILL_TO.CITY})) = 0 Then ""
else(
If (not isnull({BILL_TO.State}) and length(trim({BILL_TO.State})) <> 0)
or
(not isnull({BILL_TO.Zip}) and length(trim({BILL_TO.Zip})) <> 0)
Then ", " else "")+ {BILL_TO.CITY}))
The problem is that when there is only a city (no state or zip entered) the formula itself will not display. It does however display when the others are present.
Can anyone see a bug in this code??? Its killing me
Thanks for the help.
Look forward to hearing from you guys!
There are a whole lot of if-then-elses going on in that formula so it's hard to tell, but if it's not displaying anything that probably means that you're using a field somewhere without handling its null condition first. Something simpler might be your best bet:
local stringvar output;
if not(isnull({Customer.Postal Code})) then output:=trim({Customer.Postal Code}) + ', ';
if not(isnull({Customer.Region})) then output:=output + trim({Customer.Region}) + ', ';
if not(isnull({Customer.City})) then output:=output + trim({Customer.City}) + ', ';
left(output,length(output)-2)
Create a formula field for each database field. For example:
// {#CITY}
If Isnull({BILL_TO.CITY}) Then
""
Else
Trim({BILL_TO.CITY})
// {#STATE}
If Isnull({BILL_TO.STATE}) Then
Space(2)
Else
Trim({BILL_TO.STATE})
// {#ZIP}
If Isnull({BILL_TO.ZIP}) Then
Space(5) //adjust to meet your needs
Else
Trim({BILL_TO.ZIP})
Embed each formula field in a text object.
Format text object and its fields to meet your need.
** edit **
I you have data-quality issues, address them in the STATE and ZIP formulas (because they will be a constant length). I would add the commas and spacing the text object.

Rearrange tabs with the mouse in gvim

Is there any way in gVim to rearrange tabs by dragging and dropping them with the mouse? The behavior I'm looking for is that similar to tabs in Firefox and Chrome.
I know that it's possible to change tab order using :tabm n but that requires figuring out exactly how many tabs in you'd like to move to. Using the mouse would be more useful for this spatial task.
Any methods to move tabs left/right by one position would also be useful, since one could remap keys and move tabs without thinking too hard.
Here's what's in my vimrc regarding tabs:
" Move tabs with alt + left|right
nnoremap <silent> <A-Left> :execute 'silent! tabmove ' . (tabpagenr()-2)<CR>
nnoremap <silent> <A-Right> :execute 'silent! tabmove ' . tabpagenr()<CR>
Here is a function to move a tab to the left one position. Put it in your vimrc file and set up your keys as you see fit (to call it longhand, :execute TabLeft()).
Note that these functions "roll" tabs from first to last and last to first, respectively, so moving the first tab left makes it the last tab, and moving the last tab right makes it the first tab.
function TabLeft()
let tab_number = tabpagenr() - 1
if tab_number == 0
execute "tabm" tabpagenr('$') - 1
else
execute "tabm" tab_number - 1
endif
endfunction
...and to the right
function TabRight()
let tab_number = tabpagenr() - 1
let last_tab_number = tabpagenr('$') - 1
if tab_number == last_tab_number
execute "tabm" 0
else
execute "tabm" tab_number + 1
endif
endfunction
Thanks, and I have modified your code for my vimrc :
function ShiftTab(direction)
let tab_number = tabpagenr()
if a:direction == 0
if tab_number == 1
exe 'tabm' . tabpagenr('$')
else
exe 'tabm' . (tab_number - 2)
endif
else
if tab_number == tabpagenr('$')
exe 'tabm ' . 0
else
exe 'tabm ' . tab_number
endif
endif
return ''
endfunction
Then in my GVim, I map [ctrl+shift+left] to move left, [ctrl+shift+right] to move left
inoremap <silent> <C-S-Left> <C-r>=ShiftTab(0)<CR>
inoremap <silent> <C-S-Right> <C-r>=ShiftTab(1)<CR>
noremap <silent> <C-S-Left> :call ShiftTab(0)<CR>
noremap <silent> <C-S-Right> :call ShiftTab(1)<CR>
chris.ritsen's solution stopped working for me in vim v7.4 so here's a simpler alternative:
" Move tabs left/right
nnoremap <silent> <s-left> :-tabmove<cr>
nnoremap <silent> <s-right> :+tabmove<cr>
Ken Takata wrote a patch to do this https://groups.google.com/forum/#!msg/vim_dev/LnZVZYls1yk/PHQl4WNDAgAJ . One option is to download vim source code, aply this patch and compile.
Move Tabs to the Left / Right
This doesn't involve using a mouse, but it uses very simple keymaps for gvim:
noremap <A-[> :-tabmove<cr>
noremap <A-]> :+tabmove<cr>
Now you'll be able to move the current tab:
To the left using: Alt + [
To the right using: Alt + ]