Skip to content

Commit

Permalink
Add Vim script support and a popup menu for data lookup
Browse files Browse the repository at this point in the history
Add a new Vim script function `showdefinition()` that allows Vim script
to call back to macOS's data lookup feature and show the definition /
URL preview / etc for any text, at a designated row/col position. If the
row/col are not provided this function will just show it at the cursor.

Also, add a new autoload/macvim.vim for utility functions to call
showdefinition() for selected texts and the word under cursor. Make a
new right-click popup menu "Look Up" call that when there are selected
texts in visual mode to make the lookup functionality easier to access
for users without a trackpad (since Ctrl-Cmd-D is a little obscure and
unwieldy to use). For the utility functions, it was a little hard to
determine how to get the text under visual selection without yanking (we
don't want to pollute the register here), and just implemented a
function to take care of all the edge cases including visual/block/line
modes and selection=exclusive. It could be useful in other situations.

As a side refactor, change the message handler in MacVim from if/else to
switch case. In optimized builds, they both essentially optimize to the
same thing, but for debug builds, the if/else statements have to step
through one by one, and switch case just makes more sense for a giant
message ID lookup like this.

Part of Epic macvim-dev#1311
  • Loading branch information
ychin committed Oct 15, 2022
1 parent 31efe8c commit ea748d8
Show file tree
Hide file tree
Showing 39 changed files with 859 additions and 359 deletions.
79 changes: 79 additions & 0 deletions runtime/autoload/macvim.vim
@@ -0,0 +1,79 @@
vim9script
# Support scripts for MacVim-specific functionality
# Maintainer: Yee Cheng Chin (macvim-dev@macvim.org)
# Last Change: 2022-10-14

# Retrieves the text under the selection, without polluting the registers.
# This is easier if we could yank, but we don't know what the user has been
# doing. One way we could have accomplished this was to save the register info
# and then restore it, but this runs into problems if the unnamed register was
# pointing to the "* register as setting and restoring the system clipboard
# could be iffy (if there are non-text items in the clipboard). It's cleaner
# to just use a pure Vimscript solution without having to rely on yank.
def SelectedText(): string
var [line_start, column_start] = getpos("'<")[1 : 2]
var [line_end, column_end] = getpos("'>")[1 : 2]
final lines = getline(line_start, line_end)
if len(lines) == 0
return ''
endif

const visualmode = visualmode()

if visualmode ==# 'v'
if line_start == line_end && column_start == column_end
# Exclusive has a special case where you always select at least one
# char, so just handle the case here.
return lines[0][column_start - 1]
endif
if &selection ==# "exclusive"
column_end -= 1 # exclusive selection don't count the last column (usually)
endif
lines[-1] = lines[-1][ : column_end - 1]
lines[0] = lines[0][column_start - 1 : ]
elseif visualmode ==# "\<C-V>"
if column_end <= column_start
# This can happen with v_O, need to swap start/end
const temp = column_start
column_start = column_end
column_end = temp
# Also, exclusive mode is weird in this state in that we don't need to
# do column_end -= 1, and it acts like inclusive instead.
else
if &selection ==# "exclusive"
column_end -= 1 # normal exclusive behavior, need to cull the last column.
endif
endif
for idx in range(len(lines))
lines[idx] = lines[idx][column_start - 1 : column_end - 1]
endfor
else
# Line mode doesn't have to do anything to trim the lines
endif
return join(lines, "\n")
enddef


# Ask macOS to show the definition of the last selected text. Note that this
# uses '<, and therefore has to be used in normal mode where the mark has
# already been updated.
export def ShowDefinitionSelected()
const sel_text = SelectedText()
if len(sel_text) > 0
const sel_start = getpos("'<")
const sel_screenpos = win_getid()->screenpos(sel_start[1], sel_start[2])
showdefinition(sel_text, sel_screenpos)
endif
enddef

# Ask macOS to show the definition of the word under the cursor.
export def ShowDefinitionUnderCursor()
call search('\<', 'bc') # Go to the beginning of a word, so that showdefinition() will show the popup at the correct location.

const text = expand('<cword>')
if len(text) > 0
showdefinition(text)
endif
enddef

# vim: set sw=2 ts=2 et :
24 changes: 24 additions & 0 deletions runtime/doc/builtin.txt
Expand Up @@ -538,6 +538,8 @@ shellescape({string} [, {special}])
String escape {string} for use as shell
command argument
shiftwidth([{col}]) Number effective value of 'shiftwidth'
showdefinition({string} [, {options}])
none show definition of {string} in a popup
sign_define({name} [, {dict}]) Number define or update a sign
sign_define({list}) List define or update a list of signs
sign_getdefined([{name}]) List get a list of defined signs
Expand Down Expand Up @@ -8472,6 +8474,28 @@ shiftwidth([{col}]) *shiftwidth()*
Can also be used as a |method|: >
GetColumn()->shiftwidth()
showdefinition({string} [, {options}]) *showdefinition()*
Opens a macOS popup window showing the definition of {string}
using macOS' builtin lookup functionality. The behavior of
the lookup depends on the content of the text. Usually, it
will be the dictionary definition or Siri Knowledge article.
If it's a URL, it will show a preview of the web page; and if
it's an address, it will show a map.

This is similar to using Ctrl-Cmd-D or the trackpad to look up
data under the mouse cursor.

The location of the popup will be at the cursor. This can be
overriden by passing {options}, which should be a Dict
containing two members: "row" and "col", representing the
screen row and column to show the popup. You can also
directly pass the results of |screenpos()| to {options} as
well.

Can also be used as a |method|: >
GetText()->showdefinition()
< {only in MacVim GUI}

sign_ functions are documented here: |sign-functions-details|


Expand Down
61 changes: 45 additions & 16 deletions runtime/doc/gui_mac.txt
Expand Up @@ -14,14 +14,15 @@ The MacVim Graphical User Interface *macvim* *gui-macvim*
6. Menus |macvim-menus|
7. Toolbar |macvim-toolbar|
8. Touch Bar |macvim-touchbar|
9. Dialogs |macvim-dialogs|
10. System services |macvim-services|
11. mvim:// URL handler |macvim-url-handler|
12. Keyboard shortcuts |macvim-shortcuts|
13. Trackpad gestures |macvim-gestures|
14. International |macvim-international|
15. Known bugs/missing features |macvim-todo|
16. Hints |macvim-hints|
9. Looking up data |macvim-lookup|
10. Dialogs |macvim-dialogs|
11. System services |macvim-services|
12. mvim:// URL handler |macvim-url-handler|
13. Keyboard shortcuts |macvim-shortcuts|
14. Trackpad gestures |macvim-gestures|
15. International |macvim-international|
16. Known bugs/missing features |macvim-todo|
17. Hints |macvim-hints|

Other relevant documentation:
|gui.txt| For generic items of the GUI.
Expand Down Expand Up @@ -117,6 +118,10 @@ These are the non-standard options that MacVim supports:
These are the non-standard commands that MacVim supports:
|:macaction| |:macmenu|

*macvim-builtin-functions*
These are the non-standard builtin functions that MacVim supports:
|showdefinition()|

*macvim-autocommands*
These are the non-standard events that MacVim supports:
|OSAppearanceChanged|
Expand Down Expand Up @@ -625,7 +630,31 @@ ExitFullScreen |'fullscreen'| mode. To disable, add the following to
let g:macvim_default_touchbar_characterpicker=0
==============================================================================
9. Dialogs *macvim-dialogs*
9. Looking up data *macvim-lookup*

In macOS, you can look up the definition of the text under your cursor by
pressing Ctrl-Cmd-D, or using the trackpad (either three-finger tap or Force
click, depending on your system settings). This also works in MacVim.
Interesting data such as URL will behave differently (e.g. show a preview of
the web page linked to by the URL) as well. You can also select a piece of
text to look up the entirety of the phrase (e.g. if you select "ice cream"
using visual mode, then the definition will use that instead of just "ice" or
"cream"). There is also a right-click menu item "Look Up" available when in
visual mode to do the same thing.

If you would like to programmatically access this feature, you can call
|showdefinition()| to show the definition of whatever text you would like to.
MacVim also provides two convenient functions that you can call or map to a
key (they use |showdefinition()| internally):

`macvim#ShowDefinitionUnderCursor()` Shows the definition of the word under
the current cursor.

`macvim#ShowDefinitionSelected()` Shows the definition of the last
selected text in visual mode.

==============================================================================
10. Dialogs *macvim-dialogs*

Dialogs can be controlled with the keyboard in two ways. By default each
button in a dialog is bound to a key. The button that is highlighted by blue
Expand All @@ -644,7 +673,7 @@ select the current button. The current button is indicated with a blue
outline.

==============================================================================
10. System services *macvim-services*
11. System services *macvim-services*

MacVim supports two system services. These can be accessed from the MacVim
submenu in the Services menu or by right-clicking a selection. For services
Expand All @@ -661,7 +690,7 @@ The services respect the "Open files from applications" setting in the general
preferences.

==============================================================================
11. mvim:// URL handler *mvim://* *macvim-url-handler*
12. mvim:// URL handler *mvim://* *macvim-url-handler*

MacVim supports a custom URL handler for "mvim://" URLs. The handler is
supposed to be compatible to TextMate's URL scheme as documented at >
Expand Down Expand Up @@ -691,7 +720,7 @@ encoded once, but for best results use double-encoding as described above.
Note that url has to be a file:// url pointing to an existing local file.

==============================================================================
12. Keyboard shortcuts *macvim-shortcuts*
13. Keyboard shortcuts *macvim-shortcuts*

Most keyboard shortcuts in MacVim are bound to menu items and can be
discovered by looking through the menus (see |macvim-menus| on how to create
Expand Down Expand Up @@ -771,7 +800,7 @@ sometimes be slightly involved. Here are all the things you need to consider:
- A few command key mappings are set up by MacVim, see |cmd-movement|.

==============================================================================
13. Trackpad gestures *macvim-gestures*
14. Trackpad gestures *macvim-gestures*

MacVim supports trackpad swipe gestures. By default this can be used to
navigate back/forward in the help (try it!).
Expand Down Expand Up @@ -812,7 +841,7 @@ As another example, here is how to switch buffers by swiping left/right: >
See the section on |key-mapping| for more help on how to map keys.

==============================================================================
14. International *macvim-international* *macvim-multilang*
15. International *macvim-international* *macvim-multilang*

Typing text ~

Expand Down Expand Up @@ -843,7 +872,7 @@ messages/menus in Vim that are not currently localized. Please file an issue
if you would like to see certain messages localized.

==============================================================================
15. Known bugs/missing features *macvim-todo*
16. Known bugs/missing features *macvim-todo*

This list is by no means exhaustive, it only enumerates some of the more
prominent bugs/missing features.
Expand Down Expand Up @@ -872,7 +901,7 @@ and issues there as well: *vim_mac_group* >
http://groups.google.com/group/vim_mac
==============================================================================
16. Hints *macvim-hints*
17. Hints *macvim-hints*

In this section some general (not necessarily MacVim specific) hints are
given.
Expand Down
3 changes: 3 additions & 0 deletions runtime/doc/tags
Expand Up @@ -8373,6 +8373,7 @@ macvim-appearance gui_mac.txt /*macvim-appearance*
macvim-appearance-mode gui_mac.txt /*macvim-appearance-mode*
macvim-autocommands gui_mac.txt /*macvim-autocommands*
macvim-backspace gui_mac.txt /*macvim-backspace*
macvim-builtin-functions gui_mac.txt /*macvim-builtin-functions*
macvim-clientserver remote.txt /*macvim-clientserver*
macvim-cmdline gui_mac.txt /*macvim-cmdline*
macvim-colors gui_mac.txt /*macvim-colors*
Expand All @@ -8393,6 +8394,7 @@ macvim-hints gui_mac.txt /*macvim-hints*
macvim-internal-variables gui_mac.txt /*macvim-internal-variables*
macvim-international gui_mac.txt /*macvim-international*
macvim-login-shell gui_mac.txt /*macvim-login-shell*
macvim-lookup gui_mac.txt /*macvim-lookup*
macvim-menus gui_mac.txt /*macvim-menus*
macvim-multilang gui_mac.txt /*macvim-multilang*
macvim-options gui_mac.txt /*macvim-options*
Expand Down Expand Up @@ -9651,6 +9653,7 @@ shift intro.txt /*shift*
shift-left-right change.txt /*shift-left-right*
shiftwidth() builtin.txt /*shiftwidth()*
short-name-changed version4.txt /*short-name-changed*
showdefinition() builtin.txt /*showdefinition()*
showing-menus gui.txt /*showing-menus*
sign-column sign.txt /*sign-column*
sign-commands sign.txt /*sign-commands*
Expand Down
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_ca_es.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Mostrar\ la\ pestanya\ següent
menutrans Show\ Previous\ Tab Mostrar\ la\ pestanya\ anterior
menutrans Bring\ All\ to\ Front Portar-ho\ tot\ a\ primer\ pla
menutrans Release\ Notes Notes\ de\ la\ versió
menutrans Look\ Up Consultar
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_cs_cz.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Zobrazit\ další\ panel
menutrans Show\ Previous\ Tab Zobrazit\ předchozí\ panel
menutrans Bring\ All\ to\ Front Převést\ vše\ do\ popředí
menutrans Release\ Notes Poznámky\ k\ vydání
menutrans Look\ Up Vyhledat
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_da.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Vis\ næste\ fane
menutrans Show\ Previous\ Tab Vis\ forrige\ fane
menutrans Bring\ All\ to\ Front Anbring\ alle\ forrest
menutrans Release\ Notes Frigivelsesnoter
menutrans Look\ Up Slå\ op
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_de_de.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Nächsten\ Tab\ anzeigen
menutrans Show\ Previous\ Tab Vorherigen\ Tab\ anzeigen
menutrans Bring\ All\ to\ Front Alle\ nach\ vorne\ bringen
menutrans Release\ Notes Aktuelle\ Informationen
menutrans Look\ Up Nachschlagen
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_es_es.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Mostrar\ pestaña\ siguiente
menutrans Show\ Previous\ Tab Mostrar\ pestaña\ anterior
menutrans Bring\ All\ to\ Front Traer\ todo\ al\ frente
menutrans Release\ Notes Notas\ de\ la\ versión
menutrans Look\ Up Consultar
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_fi_fi.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Näytä\ seuraava\ välilehti
menutrans Show\ Previous\ Tab Näytä\ edellinen\ välilehti
menutrans Bring\ All\ to\ Front Tuo\ kaikki\ eteen
menutrans Release\ Notes Julkaisutiedot
menutrans Look\ Up Katso\ lisää
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_fr_fr.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Afficher\ l’onglet\ suivant
menutrans Show\ Previous\ Tab Afficher\ l’onglet\ précédent
menutrans Bring\ All\ to\ Front Tout\ ramener\ au\ premier\ plan
menutrans Release\ Notes Notes\ de\ mise\ à\ jour
menutrans Look\ Up Définition
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_hu_hu.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Következő\ lap\ megjelenítése
menutrans Show\ Previous\ Tab Előző\ lap\ megjelenítése
menutrans Bring\ All\ to\ Front Összes\ előtérbe\ hozása
menutrans Release\ Notes Kibocsátási\ megjegyzések
menutrans Look\ Up Definiálás
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_it_it.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Mostra\ pannello\ successivo
menutrans Show\ Previous\ Tab Mostra\ pannello\ precedente
menutrans Bring\ All\ to\ Front Porta\ tutto\ in\ primo\ piano
menutrans Release\ Notes Note\ di\ uscita
menutrans Look\ Up Cerca
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_ja_jp.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 次のタブを表示
menutrans Show\ Previous\ Tab 前のタブを表示
menutrans Bring\ All\ to\ Front すべてを手前に移動
menutrans Release\ Notes リリースノート
menutrans Look\ Up 調べる
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_ko_kr.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 다음\ 탭\ 보기
menutrans Show\ Previous\ Tab 이전\ \ 보기
menutrans Bring\ All\ to\ Front 모두\ 앞으로\ 가져오기
menutrans Release\ Notes 릴리즈\ 노트
menutrans Look\ Up 찾아보기
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_nl_nl.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Toon\ volgende\ tabblad
menutrans Show\ Previous\ Tab Toon\ vorige\ tabblad
menutrans Bring\ All\ to\ Front Alles\ op\ voorgrond
menutrans Release\ Notes Versienotities
menutrans Look\ Up Zoek\ op
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_no_no.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Vis\ neste\ fane
menutrans Show\ Previous\ Tab Vis\ forrige\ fane
menutrans Bring\ All\ to\ Front Legg\ alle\ øverst
menutrans Release\ Notes Merknader
menutrans Look\ Up Slå\ opp
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_pl_pl.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Pokaż\ następną\ kartę
menutrans Show\ Previous\ Tab Pokaż\ poprzednią\ kartę
menutrans Bring\ All\ to\ Front Umieść\ wszystko\ na\ wierzchu
menutrans Release\ Notes Informacje\ o\ wersji
menutrans Look\ Up Definicja
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_pt_br.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Mostrar\ Aba\ Seguinte
menutrans Show\ Previous\ Tab Mostrar\ Aba\ Anterior
menutrans Bring\ All\ to\ Front Trazer\ Todas\ para\ a\ Frente
menutrans Release\ Notes Notas\ de\ Lançamento
menutrans Look\ Up Pesquisar
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_pt_pt.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Mostrar\ separador\ seguinte
menutrans Show\ Previous\ Tab Mostrar\ separador\ anterior
menutrans Bring\ All\ to\ Front Passar\ tudo\ para\ a\ frente
menutrans Release\ Notes Notas\ de\ lançamento
menutrans Look\ Up Procurar
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_ru_ru.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Показать\ следующую\ вкладку
menutrans Show\ Previous\ Tab Показать\ предыдущую\ вкладку
menutrans Bring\ All\ to\ Front Все\ окна\ \ на\ передний\ план
menutrans Release\ Notes Примечания\ к\ выпуску
menutrans Look\ Up Найти\ в\ словаре
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_sv_se.latin1.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Visa\ nästa\ flik
menutrans Show\ Previous\ Tab Visa\ föregående\ flik
menutrans Bring\ All\ to\ Front Lägg\ alla\ överst
menutrans Release\ Notes Versions­anmärkningar
menutrans Look\ Up Slå\ upp
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_tr_tr.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Sonraki\ Sekmeyi\ Göster
menutrans Show\ Previous\ Tab Önceki\ Sekmeyi\ Göster
menutrans Bring\ All\ to\ Front Tümünü\ Öne\ Getir
menutrans Release\ Notes Çıkış\ Notları
menutrans Look\ Up Araştır
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_zh_cn.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 显示下一个标签页
menutrans Show\ Previous\ Tab 显示上一个标签页
menutrans Bring\ All\ to\ Front 前置全部窗口
menutrans Release\ Notes 发布说明
menutrans Look\ Up 查询
1 change: 1 addition & 0 deletions runtime/lang/macvim_menu/menu_zh_tw.utf-8.apple.vim
Expand Up @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 顯示下一個標籤頁
menutrans Show\ Previous\ Tab 顯示上一個標籤頁
menutrans Bring\ All\ to\ Front 將此程式所有視窗移至最前
menutrans Release\ Notes 版本附註
menutrans Look\ Up 查詢
5 changes: 5 additions & 0 deletions runtime/menu.vim
Expand Up @@ -1010,6 +1010,11 @@ an 70.410 &Window.Min\ Widt&h<Tab>^W1\| <C-W>1\|
endif " !has("gui_macvim")

" The popup menu
if has("gui_macvim")
vnoremenu 1.05 PopUp.Look\ Up :<C-U>call macvim#ShowDefinitionSelected()<CR>
vnoremenu 1.06 PopUp.-SEP10- <Nop>
endif

an 1.10 PopUp.&Undo u
an 1.15 PopUp.-SEP1- <Nop>
vnoremenu 1.20 PopUp.Cu&t "+x
Expand Down
2 changes: 2 additions & 0 deletions src/MacVim/MMBackend.h
Expand Up @@ -122,6 +122,8 @@
- (void)activate;
- (void)setPreEditRow:(int)row column:(int)col;

- (void)showDefinition:(NSString *)text row:(int)row col:(int)col;

- (int)lookupColorWithKey:(NSString *)key;
- (BOOL)hasSpecialKeyWithValue:(char_u *)value;

Expand Down

0 comments on commit ea748d8

Please sign in to comment.