Vim input: Difference between revisions

From The Toaq Wiki
(Add instructions to write Toaq in vim with a system keyboard layout)
(Using an existing keyboard layout: buffer-local + toggle)
Line 139: Line 139:


== Using an existing keyboard layout ==
== Using an existing keyboard layout ==
If you already have a Toaq keyboard layout (for example, by following [[Input_methods#XKB|the XKB instructions]]), then you can <code>:source</code> the following script to make vim automatically switch layouts depending on mode.
If you already have a Toaq keyboard layout (for example, by following [[Input_methods#XKB|the XKB instructions]]), then you can <code>:source</code> the following script to make vim automatically switch layouts depending on mode. This functionality is toggled on or off each time you source the script in the same buffer.


'''Follow the TODO instructions to make it work on your system.''' If you use an XKB method, be sure to use the name you gave your layout in evdev.lst and evdev.xml.
'''Follow the TODO instructions to make it work on your system.''' If you use an XKB method, be sure to use the name you gave your layout in evdev.lst and evdev.xml.


{{collapsible|.vimrc-toaq|<pre>" Known issues:
{{collapsible|.vimrc-toaq|<pre>" Known issues:
" 1. Modifiers do not persist through a layout switch. You need to release and re-press Shift for commands like FA. If you want a visual reminder of when the layout has changed, uncomment the lines "set cursorline! | redraw".
" 1. Modifiers do not persist through a layout switch. You need to release and re-press Shift for commands like FA.
" 2. The cursor disappears when awaiting single-character input to commands like r (actually, it moves to the command line). This is indicated by a fake "TOAQ CHAR" mode message.
" 2. The cursor visually disappears when awaiting single-character input to commands like r


" TODO: You need to choose a layout switching method from the choices below that works best for your system. Desktop Environments have their own methods of tracking and toggling the current keyboard layout. More info:
" TODO: You need to choose a layout switching method from the choices below that works best for your system. Desktop Environments have their own methods of tracking and toggling the current keyboard layout. More info:
Line 157: Line 157:


function SetNormalLayout()
function SetNormalLayout()
"TODO:
""" Method 1 (Recommended): Native method provided by *your* DE (Example: KDE Plasma 5)
""" Method 1 (Recommended): Native method provided by *your* DE (Example: KDE Plasma 5)
silent call system('qdbus org.kde.keyboard /Layouts setLayout 0')
silent call system('qdbus org.kde.keyboard /Layouts setLayout 0')
Line 169: Line 170:


function SetToaqLayout()
function SetToaqLayout()
"TODO:
silent call system('qdbus org.kde.keyboard /Layouts setLayout 1')
silent call system('qdbus org.kde.keyboard /Layouts setLayout 1')
"silent call system('setxkbmap toaq -print | xkbcomp - $DISPLAY')
"silent call system('setxkbmap toaq -print | xkbcomp - $DISPLAY')
Line 176: Line 178:
endfunction
endfunction


augroup toaq_layout_switch
""" End TODO 's """
 
if exists("b:toaq_layout_switch") && b:toaq_layout_switch
let b:toaq_layout_switch = 0
call SetNormalLayout()
redraw | echo "Disabled Toaq layout switching"
else
let b:toaq_layout_switch = 1
redraw | echo "Enabled Toaq layout switching"
endif
 
if b:toaq_layout_switch
augroup toaq_layout_switch_group_buflocal
autocmd! * <buffer>
autocmd VimEnter <buffer> call SetNormalLayout() "only matters when using -c
autocmd InsertEnter <buffer> call SetToaqLayout()
autocmd InsertLeave <buffer> call SetNormalLayout()
augroup END
else
autocmd! toaq_layout_switch_group_buflocal * <buffer>
endif
 
" These autocmds are SPECIAL because <buffer> can only be OR'd with other {aupat}s, but we want buffer-local {aupat}s.
" So instead, they will no-op if they're unwanted.
augroup toaq_layout_switch_group_global
autocmd!
autocmd!
autocmd VimEnter * call SetNormalLayout()
"autocmd VimLeave * call SetNormalLayout()
autocmd InsertEnter * call SetToaqLayout()
autocmd InsertLeave * call SetNormalLayout()
" The '/,\?' specifies search (forward, backward) only
" The '/,\?' specifies search (forward, backward) only
autocmd CmdlineEnter /,\? call SetToaqLayout()
autocmd CmdlineEnter /,\? if exists("b:toaq_layout_switch") && b:toaq_layout_switch | call SetToaqLayout() | endif
autocmd CmdlineLeave /,\? call SetNormalLayout()
autocmd CmdlineLeave /,\? if exists("b:toaq_layout_switch") && b:toaq_layout_switch | call SetNormalLayout() | endif
augroup END
augroup END


Line 199: Line 221:
endfunction
endfunction


" Normal
if b:toaq_layout_switch
nnoremap <silent> <expr> r "r" .. ToaqGetCharStr()
" Normal
nnoremap <silent> <expr> f "f" .. ToaqGetCharStr()
nnoremap <buffer> <silent> <expr> r "r" .. ToaqGetCharStr()
nnoremap <silent> <expr> F "F" .. ToaqGetCharStr()
nnoremap <buffer> <silent> <expr> f "f" .. ToaqGetCharStr()
nnoremap <silent> <expr> t "t" .. ToaqGetCharStr()
nnoremap <buffer> <silent> <expr> F "F" .. ToaqGetCharStr()
nnoremap <silent> <expr> T "T" .. ToaqGetCharStr()
nnoremap <buffer> <silent> <expr> t "t" .. ToaqGetCharStr()
" Visual
nnoremap <buffer> <silent> <expr> T "T" .. ToaqGetCharStr()
vnoremap <silent> <expr> r "r" .. ToaqGetCharStr()
" Visual
vnoremap <silent> <expr> f "f" .. ToaqGetCharStr()
vnoremap <buffer> <silent> <expr> r "r" .. ToaqGetCharStr()
vnoremap <silent> <expr> F "F" .. ToaqGetCharStr()
vnoremap <buffer> <silent> <expr> f "f" .. ToaqGetCharStr()
vnoremap <silent> <expr> t "t" .. ToaqGetCharStr()
vnoremap <buffer> <silent> <expr> F "F" .. ToaqGetCharStr()
vnoremap <silent> <expr> T "T" .. ToaqGetCharStr()
vnoremap <buffer> <silent> <expr> t "t" .. ToaqGetCharStr()
" Motions
vnoremap <buffer> <silent> <expr> T "T" .. ToaqGetCharStr()
onoremap <silent> <expr> f "f" .. ToaqGetCharStr()
" Motions
onoremap <silent> <expr> F "F" .. ToaqGetCharStr()
onoremap <buffer> <silent> <expr> f "f" .. ToaqGetCharStr()
onoremap <silent> <expr> t "t" .. ToaqGetCharStr()
onoremap <buffer> <silent> <expr> F "F" .. ToaqGetCharStr()
onoremap <silent> <expr> T "T" .. ToaqGetCharStr()
onoremap <buffer> <silent> <expr> t "t" .. ToaqGetCharStr()
onoremap <buffer> <silent> <expr> T "T" .. ToaqGetCharStr()
else
" There's a better solution here:
" https://vi.stackexchange.com/questions/7734/how-to-save-and-restore-a-mapping
 
" Normal
nunmap <buffer> r
nunmap <buffer> f
nunmap <buffer> F
nunmap <buffer> t
nunmap <buffer> T
" Visual
vunmap <buffer> r
vunmap <buffer> f
vunmap <buffer> F
vunmap <buffer> t
vunmap <buffer> T
" Motions
ounmap <buffer> f
ounmap <buffer> F
ounmap <buffer> t
ounmap <buffer> T
endif
</pre>}}
</pre>}}


You might want to add a mapping to your <code>~/.vimrc</code> to quickly source the script:
You might want to add mappings to your <code>~/.vimrc</code> to quickly source the script:


<code>noremap <Leader>t :source ~/.vimrc-toaq</code>
<pre>noremap <Leader>t :source ~/.vimrc-toaq<CR> " toggle in current buffer
noremap <Leader>T :windo source ~/.vimrc_toaq<CR> " toggle in every window</pre>


[[Category:Input methods]]
[[Category:Input methods]]

Revision as of 04:01, 22 September 2024

This article explains how to write Toaq in the text editor vim.

Using a keymap

Copy the contents below into a file called toaq.vim inside a folder named keymap in your .vim directory (create it if it doesn’t exist). Then, in insert mode, you may use any of the two-keystroke “combinations” and have them replaced with accented letters on the fly. (See :help mbyte-keymap for more detailed information.)

Without underdot With underdot
falling tone .
rising tone / '
glottal tone : "
hiatus tone > ^
Toaq vim keymap
" toaq keymap
" by uakci on 2022-12-20
scriptencoding utf8
let b:keymap_name = "toaq"
loadkeymap
.i	i
i	ı
//	/
::	:
>>	>
''	'
""	"
^^	^
..	.
.<	«
.>	»
.{	‹
.}	›
./	́
.:	̈
.>	̂
.,	̣
.A	Ạ
.U	Ụ
.I	Ị
.O	Ọ
.E	Ẹ
.a	ạ
.u	ụ
.i	ı̣
.o	ọ
.e	ẹ
vy	ꝡ
Vy	Ꝡ
VY	Ꝡ
/A	Á
/U	Ú
/I	Í
/O	Ó
/E	É
/a	á
/u	ú
/i	í
/o	ó
/e	é
:A	Ä
:U	Ü
:I	Ï
:O	Ö
:E	Ë
:a	ä
:u	ü
:i	ï
:o	ö
:e	ë
>A	Â
>U	Û
>I	Î
>O	Ô
>E	Ê
>a	â
>u	û
>i	î
>o	ô
>e	ê
'A	Ạ́
'U	Ụ́
'I	Ị́
'O	Ọ́
'E	Ẹ́
'a	ạ́
'u	ụ́
'i	ị́
'o	ọ́
'e	ẹ́
"A	Ạ̈
"U	Ụ̈
"I	Ị̈
"O	Ọ̈
"E	Ẹ̈
"a	ạ̈
"u	ụ̈
"i	ị̈
"o	ọ̈
"e	ẹ̈
^A	Ậ
^U	Ụ̂
^I	Ị̂
^O	Ộ
^E	Ệ
^a	ậ
^u	ụ̂
^i	ị̂
^o	ộ
^e	ệ

Using digraphs

Alternatively, for sporadic usage, you can enter Toaq characters using Ctrl+K followed by two keystrokes (see :help digraph). Ꝡ is not available to input using this method.

Character Combo
rising tone Ctrl+K vowel '
glottal tone Ctrl+K vowel :
hiatus tone Ctrl+K vowel >
dotless i (ı) Ctrl+K . i
left quote («) Ctrl+K < <
right quote (») Ctrl+K > >

Using an existing keyboard layout

If you already have a Toaq keyboard layout (for example, by following the XKB instructions), then you can :source the following script to make vim automatically switch layouts depending on mode. This functionality is toggled on or off each time you source the script in the same buffer.

Follow the TODO instructions to make it work on your system. If you use an XKB method, be sure to use the name you gave your layout in evdev.lst and evdev.xml.

.vimrc-toaq
" Known issues:
" 1. Modifiers do not persist through a layout switch. You need to release and re-press Shift for commands like FA.
" 2. The cursor visually disappears when awaiting single-character input to commands like r

" TODO: You need to choose a layout switching method from the choices below that works best for your system. Desktop Environments have their own methods of tracking and toggling the current keyboard layout. More info:
" 	https://unix.stackexchange.com/questions/402719/how-to-get-current-keyboard-layout-from-the-command-line
" In the examples, the layout-variant pairs are:
"  Layout   Variant
" --------+---------------
"  us     | dvorak
" --------+---------------
"  toaq   | [empty string]

function SetNormalLayout()
	"TODO:
	""" Method 1 (Recommended): Native method provided by *your* DE (Example: KDE Plasma 5)
	silent call system('qdbus org.kde.keyboard /Layouts setLayout 0')
	""" Method 2 (XKB): Set directly with xkbcomp. Likely to pakala your DE.
	"silent call system('setxkbmap us dvorak -print | xkbcomp - $DISPLAY')
	""" Method 3 (XKB): Switch order of keymaps reported by X to trick DE. Can cause odd problems, but might play nicer. Get this info from 'setxkbmap -query'.
	"silent call system('setxkbmap -layout us,toaq -variant dvorak,')
	""" Method 4 (Untested): xdotool to simulate keyboard toggle key shortcut(s).

	"set cursorline! | redraw
endfunction

function SetToaqLayout()
	"TODO:
	silent call system('qdbus org.kde.keyboard /Layouts setLayout 1')
	"silent call system('setxkbmap toaq -print | xkbcomp - $DISPLAY')
	"silent call system('setxkbmap -layout toaq,us -variant ,dvorak')

	"set cursorline! | redraw
endfunction

""" End TODO 's """

if exists("b:toaq_layout_switch") && b:toaq_layout_switch
	let b:toaq_layout_switch = 0
	call SetNormalLayout()
	redraw | echo "Disabled Toaq layout switching"
else
	let b:toaq_layout_switch = 1
	redraw | echo "Enabled Toaq layout switching"
endif

if b:toaq_layout_switch
	augroup toaq_layout_switch_group_buflocal
		autocmd! * <buffer>
		autocmd VimEnter <buffer> call SetNormalLayout() "only matters when using -c
		autocmd InsertEnter <buffer> call SetToaqLayout()
		autocmd InsertLeave <buffer> call SetNormalLayout()
	augroup END
else
	autocmd! toaq_layout_switch_group_buflocal * <buffer>
endif

" These autocmds are SPECIAL because <buffer> can only be OR'd with other {aupat}s, but we want buffer-local {aupat}s.
" So instead, they will no-op if they're unwanted.
augroup toaq_layout_switch_group_global
	autocmd!
	" The '/,\?' specifies search (forward, backward) only
	autocmd CmdlineEnter /,\? if exists("b:toaq_layout_switch") && b:toaq_layout_switch | call SetToaqLayout() | endif
	autocmd CmdlineLeave /,\? if exists("b:toaq_layout_switch") && b:toaq_layout_switch | call SetNormalLayout() | endif
augroup END

""" Remap some odd commands which expect buffer chars in operator-pending mode to work with Toaq buffer text. Overrides previous mappings!
" For example, you can type rı or ctꝡ from normal mode.

function ToaqGetCharStr()
	call SetToaqLayout()
	echohl ModeMsg | echo '-- TOAQ CHAR -- ' | echohl None
	let c = getcharstr()
	echo ''
	call SetNormalLayout()
	return c
endfunction

if b:toaq_layout_switch
	" Normal
	nnoremap <buffer> <silent> <expr> r "r" .. ToaqGetCharStr()
	nnoremap <buffer> <silent> <expr> f "f" .. ToaqGetCharStr()
	nnoremap <buffer> <silent> <expr> F "F" .. ToaqGetCharStr()
	nnoremap <buffer> <silent> <expr> t "t" .. ToaqGetCharStr()
	nnoremap <buffer> <silent> <expr> T "T" .. ToaqGetCharStr()
	" Visual
	vnoremap <buffer> <silent> <expr> r "r" .. ToaqGetCharStr()
	vnoremap <buffer> <silent> <expr> f "f" .. ToaqGetCharStr()
	vnoremap <buffer> <silent> <expr> F "F" .. ToaqGetCharStr()
	vnoremap <buffer> <silent> <expr> t "t" .. ToaqGetCharStr()
	vnoremap <buffer> <silent> <expr> T "T" .. ToaqGetCharStr()
	" Motions
	onoremap <buffer> <silent> <expr> f "f" .. ToaqGetCharStr()
	onoremap <buffer> <silent> <expr> F "F" .. ToaqGetCharStr()
	onoremap <buffer> <silent> <expr> t "t" .. ToaqGetCharStr()
	onoremap <buffer> <silent> <expr> T "T" .. ToaqGetCharStr()
else
	" There's a better solution here:
	" 	https://vi.stackexchange.com/questions/7734/how-to-save-and-restore-a-mapping

	" Normal
	nunmap <buffer> r
	nunmap <buffer> f
	nunmap <buffer> F
	nunmap <buffer> t
	nunmap <buffer> T
	" Visual
	vunmap <buffer> r
	vunmap <buffer> f
	vunmap <buffer> F
	vunmap <buffer> t
	vunmap <buffer> T
	" Motions
	ounmap <buffer> f
	ounmap <buffer> F
	ounmap <buffer> t
	ounmap <buffer> T
endif

You might want to add mappings to your ~/.vimrc to quickly source the script:

noremap <Leader>t :source ~/.vimrc-toaq<CR> " toggle in current buffer
noremap <Leader>T :windo source ~/.vimrc_toaq<CR> " toggle in every window