diff --git a/runtime/autoload/macvim.vim b/runtime/autoload/macvim.vim new file mode 100644 index 0000000000..da8396a49a --- /dev/null +++ b/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 ==# "\" + 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('') + if len(text) > 0 + showdefinition(text) + endif +enddef + +# vim: set sw=2 ts=2 et : diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index c2283358b8..de8def0fdb 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -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 @@ -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| diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt index 65fc6551ae..1f0e3c0c3a 100644 --- a/runtime/doc/gui_mac.txt +++ b/runtime/doc/gui_mac.txt @@ -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. @@ -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| @@ -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 @@ -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 @@ -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 > @@ -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 @@ -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!). @@ -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 ~ @@ -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. @@ -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. diff --git a/runtime/doc/tags b/runtime/doc/tags index 57e18d71b6..d1f3dcff05 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -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* @@ -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* @@ -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* diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 97e1d5ce91..154b3ae11e 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -1379,6 +1379,9 @@ Various: *various-functions* debugbreak() interrupt a program being debugged +MacVim-specific functions + showdefinition() look up and show definition of provided string + ============================================================================== *41.7* Defining a function diff --git a/runtime/lang/macvim_menu/menu_ca_es.latin1.apple.vim b/runtime/lang/macvim_menu/menu_ca_es.latin1.apple.vim index fe04bde0ea..528f39dc78 100644 --- a/runtime/lang/macvim_menu/menu_ca_es.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_ca_es.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_cs_cz.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_cs_cz.utf-8.apple.vim index 61b214a80d..c2ecd17ae1 100644 --- a/runtime/lang/macvim_menu/menu_cs_cz.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_cs_cz.utf-8.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_da.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_da.utf-8.apple.vim index ac36fd7276..6cde565afe 100644 --- a/runtime/lang/macvim_menu/menu_da.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_da.utf-8.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_de_de.latin1.apple.vim b/runtime/lang/macvim_menu/menu_de_de.latin1.apple.vim index 8328fcf5da..8804a0c914 100644 --- a/runtime/lang/macvim_menu/menu_de_de.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_de_de.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_es_es.latin1.apple.vim b/runtime/lang/macvim_menu/menu_es_es.latin1.apple.vim index fc5e179f73..008737b8bb 100644 --- a/runtime/lang/macvim_menu/menu_es_es.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_es_es.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_fi_fi.latin1.apple.vim b/runtime/lang/macvim_menu/menu_fi_fi.latin1.apple.vim index 1ec0d7a45c..c697531e8f 100644 --- a/runtime/lang/macvim_menu/menu_fi_fi.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_fi_fi.latin1.apple.vim @@ -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ää diff --git a/runtime/lang/macvim_menu/menu_fr_fr.latin1.apple.vim b/runtime/lang/macvim_menu/menu_fr_fr.latin1.apple.vim index 9b5ddecee0..ba4564ec95 100644 --- a/runtime/lang/macvim_menu/menu_fr_fr.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_fr_fr.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_hu_hu.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_hu_hu.utf-8.apple.vim index 2d2ec3b70d..249f2ce8e7 100644 --- a/runtime/lang/macvim_menu/menu_hu_hu.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_hu_hu.utf-8.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_it_it.latin1.apple.vim b/runtime/lang/macvim_menu/menu_it_it.latin1.apple.vim index 061f5f8fe3..79e8f3e481 100644 --- a/runtime/lang/macvim_menu/menu_it_it.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_it_it.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_ja_jp.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_ja_jp.utf-8.apple.vim index 16ed67a651..8ea9acc8c3 100644 --- a/runtime/lang/macvim_menu/menu_ja_jp.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_ja_jp.utf-8.apple.vim @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 次のタブを表示 menutrans Show\ Previous\ Tab 前のタブを表示 menutrans Bring\ All\ to\ Front すべてを手前に移動 menutrans Release\ Notes リリースノート +menutrans Look\ Up 調べる diff --git a/runtime/lang/macvim_menu/menu_ko_kr.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_ko_kr.utf-8.apple.vim index fd36136473..173fa86414 100644 --- a/runtime/lang/macvim_menu/menu_ko_kr.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_ko_kr.utf-8.apple.vim @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 다음\ 탭\ 보기 menutrans Show\ Previous\ Tab 이전\ 탭\ 보기 menutrans Bring\ All\ to\ Front 모두\ 앞으로\ 가져오기 menutrans Release\ Notes 릴리즈\ 노트 +menutrans Look\ Up 찾아보기 diff --git a/runtime/lang/macvim_menu/menu_nl_nl.latin1.apple.vim b/runtime/lang/macvim_menu/menu_nl_nl.latin1.apple.vim index fdcbca6ab4..c6b7378a4f 100644 --- a/runtime/lang/macvim_menu/menu_nl_nl.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_nl_nl.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_no_no.latin1.apple.vim b/runtime/lang/macvim_menu/menu_no_no.latin1.apple.vim index 7a96b895c2..b0c06e6c4b 100644 --- a/runtime/lang/macvim_menu/menu_no_no.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_no_no.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_pl_pl.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_pl_pl.utf-8.apple.vim index bf581cd4fb..83d85f7046 100644 --- a/runtime/lang/macvim_menu/menu_pl_pl.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_pl_pl.utf-8.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_pt_br.apple.vim b/runtime/lang/macvim_menu/menu_pt_br.apple.vim index 19867e43e4..7e910b288a 100644 --- a/runtime/lang/macvim_menu/menu_pt_br.apple.vim +++ b/runtime/lang/macvim_menu/menu_pt_br.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_pt_pt.apple.vim b/runtime/lang/macvim_menu/menu_pt_pt.apple.vim index dee1b0238b..da9c823aca 100644 --- a/runtime/lang/macvim_menu/menu_pt_pt.apple.vim +++ b/runtime/lang/macvim_menu/menu_pt_pt.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_ru_ru.apple.vim b/runtime/lang/macvim_menu/menu_ru_ru.apple.vim index 3bcc329608..4265f32134 100644 --- a/runtime/lang/macvim_menu/menu_ru_ru.apple.vim +++ b/runtime/lang/macvim_menu/menu_ru_ru.apple.vim @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab Показать\ следующую\ вкладку menutrans Show\ Previous\ Tab Показать\ предыдущую\ вкладку menutrans Bring\ All\ to\ Front Все\ окна\ —\ на\ передний\ план menutrans Release\ Notes Примечания\ к\ выпуску +menutrans Look\ Up Найти\ в\ словаре diff --git a/runtime/lang/macvim_menu/menu_sv_se.latin1.apple.vim b/runtime/lang/macvim_menu/menu_sv_se.latin1.apple.vim index 6d6407432b..ef87fa6220 100644 --- a/runtime/lang/macvim_menu/menu_sv_se.latin1.apple.vim +++ b/runtime/lang/macvim_menu/menu_sv_se.latin1.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_tr_tr.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_tr_tr.utf-8.apple.vim index 345339fb80..b5b3fe0e49 100644 --- a/runtime/lang/macvim_menu/menu_tr_tr.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_tr_tr.utf-8.apple.vim @@ -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 diff --git a/runtime/lang/macvim_menu/menu_zh_cn.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_zh_cn.utf-8.apple.vim index 0dcee4384b..646715734a 100644 --- a/runtime/lang/macvim_menu/menu_zh_cn.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_zh_cn.utf-8.apple.vim @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 显示下一个标签页 menutrans Show\ Previous\ Tab 显示上一个标签页 menutrans Bring\ All\ to\ Front 前置全部窗口 menutrans Release\ Notes 发布说明 +menutrans Look\ Up 查询 diff --git a/runtime/lang/macvim_menu/menu_zh_tw.utf-8.apple.vim b/runtime/lang/macvim_menu/menu_zh_tw.utf-8.apple.vim index 84d3a46966..d631ad8aee 100644 --- a/runtime/lang/macvim_menu/menu_zh_tw.utf-8.apple.vim +++ b/runtime/lang/macvim_menu/menu_zh_tw.utf-8.apple.vim @@ -26,3 +26,4 @@ menutrans Show\ Next\ Tab 顯示下一個標籤頁 menutrans Show\ Previous\ Tab 顯示上一個標籤頁 menutrans Bring\ All\ to\ Front 將此程式所有視窗移至最前 menutrans Release\ Notes 版本附註 +menutrans Look\ Up 查詢 diff --git a/runtime/menu.vim b/runtime/menu.vim index c8fd60e563..4d3756c049 100644 --- a/runtime/menu.vim +++ b/runtime/menu.vim @@ -1010,6 +1010,11 @@ an 70.410 &Window.Min\ Widt&h^W1\| 1\| endif " !has("gui_macvim") " The popup menu +if has("gui_macvim") + vnoremenu 1.05 PopUp.Look\ Up :call macvim#ShowDefinitionSelected() + vnoremenu 1.06 PopUp.-SEP10- +endif + an 1.10 PopUp.&Undo u an 1.15 PopUp.-SEP1- vnoremenu 1.20 PopUp.Cu&t "+x diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index b05c9e9f95..f0141da736 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -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; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index a891c81491..a2cdef1865 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -1104,6 +1104,20 @@ - (void)setPreEditRow:(int)row column:(int)col [self queueMessage:SetPreEditPositionMsgID data:data]; } +- (void)showDefinition:(NSString *)text row:(int)row col:(int)col +{ + NSMutableData *data = [NSMutableData data]; + [data appendBytes:&row length:sizeof(int)]; + [data appendBytes:&col length:sizeof(int)]; + + NSUInteger len = [text lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + [data appendBytes:&len length:sizeof(NSUInteger)]; + if (len > 0) + [data appendBytes:[text UTF8String] length:len]; + + [self queueMessage:ShowDefinitionMsgID data:data]; +} + - (int)lookupColorWithKey:(NSString *)key { if (!(key && [key length] > 0)) diff --git a/src/MacVim/MMCoreTextView.h b/src/MacVim/MMCoreTextView.h index eb57b45e94..9cce724dee 100644 --- a/src/MacVim/MMCoreTextView.h +++ b/src/MacVim/MMCoreTextView.h @@ -140,6 +140,7 @@ - (NSRect)rectForRow:(int)row column:(int)column numRows:(int)nr numColumns:(int)nc; - (void)updateCmdlineRow; +- (void)showDefinitionForCustomString:(NSString *)text row:(int)row col:(int)col; // // NSTextView methods diff --git a/src/MacVim/MMCoreTextView.m b/src/MacVim/MMCoreTextView.m index 425d96672f..85a169fcc5 100644 --- a/src/MacVim/MMCoreTextView.m +++ b/src/MacVim/MMCoreTextView.m @@ -565,6 +565,22 @@ - (void)updateCmdlineRow [self setCmdlineRow: [[[self vimController] objectForVimStateKey:@"cmdline_row"] intValue]]; } +/// Shows the dictionary looup / definition of the provided text at row/col. +/// This is usually invoked from Vimscript via the showdefinition() function. +- (void)showDefinitionForCustomString:(NSString *)text row:(int)row col:(int)col +{ + const NSRect cursorRect = [self rectForRow:row column:col numRows:1 numColumns:1]; + + NSPoint baselinePt = cursorRect.origin; + baselinePt.y += fontDescent; + + NSAttributedString *attrText = [[[NSAttributedString alloc] initWithString:text + attributes:@{NSFontAttributeName: font} + ] autorelease]; + + [self showDefinitionForAttributedString:attrText atPoint:baselinePt]; +} + - (void)setImControl:(BOOL)enable { [helper setImControl:enable]; diff --git a/src/MacVim/MMTextView.h b/src/MacVim/MMTextView.h index c6430d2542..036192c1a8 100644 --- a/src/MacVim/MMTextView.h +++ b/src/MacVim/MMTextView.h @@ -41,6 +41,7 @@ - (void)checkImState; - (void)refreshFonts; - (void)updateCmdlineRow; +- (void)showDefinitionForCustomString:(NSString *)text row:(int)row col:(int)col; // // MMTextStorage methods diff --git a/src/MacVim/MMTextView.m b/src/MacVim/MMTextView.m index 26cd20d8ac..0702f7cecf 100644 --- a/src/MacVim/MMTextView.m +++ b/src/MacVim/MMTextView.m @@ -362,6 +362,11 @@ - (void)updateCmdlineRow // Doesn't do anything. CoreText renderer only. } +- (void)showDefinitionForCustomString:(NSString *)text row:(int)row col:(int)col; +{ + // Doesn't do anything. CoreText renderer only. +} + - (NSSize)cellSize { return [(MMTextStorage*)[self textStorage] cellSize]; diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 42097cb143..de28ea1574 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -668,358 +668,559 @@ - (void)doProcessInputQueue:(NSArray *)queue - (void)handleMessage:(int)msgid data:(NSData *)data { - if (OpenWindowMsgID == msgid) { - [windowController openWindow]; - if (!isPreloading) { - [windowController presentWindow:nil]; - } - } else if (BatchDrawMsgID == msgid) { - [[[windowController vimView] textView] performBatchDrawWithData:data]; - } else if (SelectTabMsgID == msgid) { -#if 0 // NOTE: Tab selection is done inside updateTabsWithData:. - const void *bytes = [data bytes]; - int idx = *((int*)bytes); - [windowController selectTabWithIndex:idx]; -#endif - } else if (UpdateTabBarMsgID == msgid) { - [windowController updateTabsWithData:data]; - } else if (ShowTabBarMsgID == msgid) { - [windowController showTabBar:YES]; - [self sendMessage:BackingPropertiesChangedMsgID data:nil]; - } else if (HideTabBarMsgID == msgid) { - [windowController showTabBar:NO]; - [self sendMessage:BackingPropertiesChangedMsgID data:nil]; - } else if (SetTextDimensionsMsgID == msgid || LiveResizeMsgID == msgid || - SetTextDimensionsNoResizeWindowMsgID == msgid || - SetTextDimensionsReplyMsgID == msgid) { - const void *bytes = [data bytes]; - int rows = *((int*)bytes); bytes += sizeof(int); - int cols = *((int*)bytes); - - // NOTE: When a resize message originated in the frontend, Vim - // acknowledges it with a reply message. When this happens the window - // should not move (the frontend would already have moved the window). - BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid; - - BOOL keepGUISize = SetTextDimensionsNoResizeWindowMsgID == msgid; - - [windowController setTextDimensionsWithRows:rows - columns:cols - isLive:(LiveResizeMsgID==msgid) - keepGUISize:keepGUISize - keepOnScreen:onScreen]; - } else if (ResizeViewMsgID == msgid) { - [windowController resizeView]; - } else if (SetWindowTitleMsgID == msgid) { - const void *bytes = [data bytes]; - int len = *((int*)bytes); bytes += sizeof(int); - - NSString *string = [[NSString alloc] initWithBytes:(void*)bytes - length:len encoding:NSUTF8StringEncoding]; - - [windowController setTitle:string]; - - [string release]; - } else if (SetDocumentFilenameMsgID == msgid) { - const void *bytes = [data bytes]; - int len = *((int*)bytes); bytes += sizeof(int); - - if (len > 0) { - NSString *filename = [[NSString alloc] initWithBytes:(void*)bytes + switch (msgid) { + case OpenWindowMsgID: + { + [windowController openWindow]; + if (!isPreloading) { + [windowController presentWindow:nil]; + } + } + break; + case BatchDrawMsgID: + { + [[[windowController vimView] textView] performBatchDrawWithData:data]; + } + break; + case SelectTabMsgID: + { + #if 0 // NOTE: Tab selection is done inside updateTabsWithData:. + const void *bytes = [data bytes]; + int idx = *((int*)bytes); + [windowController selectTabWithIndex:idx]; + #endif + } + break; + case UpdateTabBarMsgID: + { + [windowController updateTabsWithData:data]; + } + break; + case ShowTabBarMsgID: + { + [windowController showTabBar:YES]; + [self sendMessage:BackingPropertiesChangedMsgID data:nil]; + } + break; + case HideTabBarMsgID: + { + [windowController showTabBar:NO]; + [self sendMessage:BackingPropertiesChangedMsgID data:nil]; + } + break; + + case SetTextDimensionsMsgID: + case LiveResizeMsgID: + case SetTextDimensionsNoResizeWindowMsgID: + case SetTextDimensionsReplyMsgID: + { + const void *bytes = [data bytes]; + int rows = *((int*)bytes); bytes += sizeof(int); + int cols = *((int*)bytes); + + // NOTE: When a resize message originated in the frontend, Vim + // acknowledges it with a reply message. When this happens the window + // should not move (the frontend would already have moved the window). + BOOL onScreen = SetTextDimensionsReplyMsgID!=msgid; + + BOOL keepGUISize = SetTextDimensionsNoResizeWindowMsgID == msgid; + + [windowController setTextDimensionsWithRows:rows + columns:cols + isLive:(LiveResizeMsgID==msgid) + keepGUISize:keepGUISize + keepOnScreen:onScreen]; + } + break; + + case ResizeViewMsgID: + { + [windowController resizeView]; + } + break; + case SetWindowTitleMsgID: + { + const void *bytes = [data bytes]; + int len = *((int*)bytes); bytes += sizeof(int); + + NSString *string = [[NSString alloc] initWithBytes:(void*)bytes length:len encoding:NSUTF8StringEncoding]; - [windowController setDocumentFilename:filename]; + [windowController setTitle:string]; - [filename release]; - } else { - [windowController setDocumentFilename:@""]; - } - } else if (AddMenuMsgID == msgid) { - NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; - [self addMenuWithDescriptor:[attrs objectForKey:@"descriptor"] - atIndex:[[attrs objectForKey:@"index"] intValue]]; - } else if (AddMenuItemMsgID == msgid) { - NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; - [self addMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"] - atIndex:[[attrs objectForKey:@"index"] intValue] - tip:[attrs objectForKey:@"tip"] - icon:[attrs objectForKey:@"icon"] - keyEquivalent:[attrs objectForKey:@"keyEquivalent"] - modifierMask:[[attrs objectForKey:@"modifierMask"] intValue] - action:[attrs objectForKey:@"action"] - isAlternate:[[attrs objectForKey:@"isAlternate"] boolValue]]; - } else if (RemoveMenuItemMsgID == msgid) { - NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; - [self removeMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"]]; - } else if (EnableMenuItemMsgID == msgid) { - NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; - [self enableMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"] - state:[[attrs objectForKey:@"enable"] boolValue]]; - } else if (UpdateMenuItemTooltipMsgID == msgid) { - NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; - [self updateMenuItemTooltipWithDescriptor:[attrs objectForKey:@"descriptor"] - tip:[attrs objectForKey:@"tip"]]; - } else if (ShowToolbarMsgID == msgid) { - const void *bytes = [data bytes]; - int enable = *((int*)bytes); bytes += sizeof(int); - int flags = *((int*)bytes); - - int mode = NSToolbarDisplayModeDefault; - if (flags & ToolbarLabelFlag) { - mode = flags & ToolbarIconFlag ? NSToolbarDisplayModeIconAndLabel - : NSToolbarDisplayModeLabelOnly; - } else if (flags & ToolbarIconFlag) { - mode = NSToolbarDisplayModeIconOnly; - } - - int size = flags & ToolbarSizeRegularFlag ? NSToolbarSizeModeRegular - : NSToolbarSizeModeSmall; - - [windowController showToolbar:enable size:size mode:mode]; - } else if (CreateScrollbarMsgID == msgid) { - const void *bytes = [data bytes]; - int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); - int type = *((int*)bytes); - - [windowController createScrollbarWithIdentifier:ident type:type]; - } else if (DestroyScrollbarMsgID == msgid) { - const void *bytes = [data bytes]; - int32_t ident = *((int32_t*)bytes); - - [windowController destroyScrollbarWithIdentifier:ident]; - } else if (ShowScrollbarMsgID == msgid) { - const void *bytes = [data bytes]; - int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); - int visible = *((int*)bytes); - - [windowController showScrollbarWithIdentifier:ident state:visible]; - } else if (SetScrollbarPositionMsgID == msgid) { - const void *bytes = [data bytes]; - int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); - int pos = *((int*)bytes); bytes += sizeof(int); - int len = *((int*)bytes); - - [windowController setScrollbarPosition:pos length:len - identifier:ident]; - } else if (SetScrollbarThumbMsgID == msgid) { - const void *bytes = [data bytes]; - int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); - float val = *((float*)bytes); bytes += sizeof(float); - float prop = *((float*)bytes); - - [windowController setScrollbarThumbValue:val proportion:prop - identifier:ident]; - } else if (SetFontMsgID == msgid) { - const void *bytes = [data bytes]; - float size = *((float*)bytes); bytes += sizeof(float); - int len = *((int*)bytes); bytes += sizeof(int); - NSString *name = [[NSString alloc] - initWithBytes:(void*)bytes length:len - encoding:NSUTF8StringEncoding]; - NSFont *font = [NSFont fontWithName:name size:size]; - if (!font) { - // This should only happen if the system default font has changed - // name since MacVim was compiled in which case we fall back on - // using the user fixed width font. - ASLogInfo(@"Failed to load font '%@' / %f", name, size); - font = [NSFont userFixedPitchFontOfSize:size]; - } - - [windowController setFont:font]; - [name release]; - } else if (SetWideFontMsgID == msgid) { - const void *bytes = [data bytes]; - float size = *((float*)bytes); bytes += sizeof(float); - int len = *((int*)bytes); bytes += sizeof(int); - if (len > 0) { + [string release]; + } + break; + case SetDocumentFilenameMsgID: + { + const void *bytes = [data bytes]; + int len = *((int*)bytes); bytes += sizeof(int); + + if (len > 0) { + NSString *filename = [[NSString alloc] initWithBytes:(void*)bytes + length:len encoding:NSUTF8StringEncoding]; + + [windowController setDocumentFilename:filename]; + + [filename release]; + } else { + [windowController setDocumentFilename:@""]; + } + } + break; + case AddMenuMsgID: + { + NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; + [self addMenuWithDescriptor:[attrs objectForKey:@"descriptor"] + atIndex:[[attrs objectForKey:@"index"] intValue]]; + } + break; + case AddMenuItemMsgID: + { + NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; + [self addMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"] + atIndex:[[attrs objectForKey:@"index"] intValue] + tip:[attrs objectForKey:@"tip"] + icon:[attrs objectForKey:@"icon"] + keyEquivalent:[attrs objectForKey:@"keyEquivalent"] + modifierMask:[[attrs objectForKey:@"modifierMask"] intValue] + action:[attrs objectForKey:@"action"] + isAlternate:[[attrs objectForKey:@"isAlternate"] boolValue]]; + } + break; + case RemoveMenuItemMsgID: + { + NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; + [self removeMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"]]; + } + break; + case EnableMenuItemMsgID: + { + NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; + [self enableMenuItemWithDescriptor:[attrs objectForKey:@"descriptor"] + state:[[attrs objectForKey:@"enable"] boolValue]]; + } + break; + case UpdateMenuItemTooltipMsgID: + { + NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; + [self updateMenuItemTooltipWithDescriptor:[attrs objectForKey:@"descriptor"] + tip:[attrs objectForKey:@"tip"]]; + } + break; + case ShowToolbarMsgID: + { + const void *bytes = [data bytes]; + int enable = *((int*)bytes); bytes += sizeof(int); + int flags = *((int*)bytes); + + int mode = NSToolbarDisplayModeDefault; + if (flags & ToolbarLabelFlag) { + mode = flags & ToolbarIconFlag ? NSToolbarDisplayModeIconAndLabel + : NSToolbarDisplayModeLabelOnly; + } else if (flags & ToolbarIconFlag) { + mode = NSToolbarDisplayModeIconOnly; + } + + int size = flags & ToolbarSizeRegularFlag ? NSToolbarSizeModeRegular + : NSToolbarSizeModeSmall; + + [windowController showToolbar:enable size:size mode:mode]; + } + break; + case CreateScrollbarMsgID: + { + const void *bytes = [data bytes]; + int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); + int type = *((int*)bytes); + + [windowController createScrollbarWithIdentifier:ident type:type]; + } + break; + case DestroyScrollbarMsgID: + { + const void *bytes = [data bytes]; + int32_t ident = *((int32_t*)bytes); + + [windowController destroyScrollbarWithIdentifier:ident]; + } + break; + case ShowScrollbarMsgID: + { + const void *bytes = [data bytes]; + int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); + int visible = *((int*)bytes); + + [windowController showScrollbarWithIdentifier:ident state:visible]; + } + break; + case SetScrollbarPositionMsgID: + { + const void *bytes = [data bytes]; + int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); + int pos = *((int*)bytes); bytes += sizeof(int); + int len = *((int*)bytes); + + [windowController setScrollbarPosition:pos length:len + identifier:ident]; + } + break; + case SetScrollbarThumbMsgID: + { + const void *bytes = [data bytes]; + int32_t ident = *((int32_t*)bytes); bytes += sizeof(int32_t); + float val = *((float*)bytes); bytes += sizeof(float); + float prop = *((float*)bytes); + + [windowController setScrollbarThumbValue:val proportion:prop + identifier:ident]; + } + break; + case SetFontMsgID: + { + const void *bytes = [data bytes]; + float size = *((float*)bytes); bytes += sizeof(float); + int len = *((int*)bytes); bytes += sizeof(int); NSString *name = [[NSString alloc] initWithBytes:(void*)bytes length:len encoding:NSUTF8StringEncoding]; NSFont *font = [NSFont fontWithName:name size:size]; - [windowController setWideFont:font]; + if (!font) { + // This should only happen if the system default font has changed + // name since MacVim was compiled in which case we fall back on + // using the user fixed width font. + ASLogInfo(@"Failed to load font '%@' / %f", name, size); + font = [NSFont userFixedPitchFontOfSize:size]; + } + [windowController setFont:font]; [name release]; - } else { - [windowController setWideFont:nil]; - } - } else if (SetDefaultColorsMsgID == msgid) { - const void *bytes = [data bytes]; - unsigned bg = *((unsigned*)bytes); bytes += sizeof(unsigned); - unsigned fg = *((unsigned*)bytes); - NSColor *back = [NSColor colorWithArgbInt:bg]; - NSColor *fore = [NSColor colorWithRgbInt:fg]; - - [windowController setDefaultColorsBackground:back foreground:fore]; - } else if (ExecuteActionMsgID == msgid) { - const void *bytes = [data bytes]; - int len = *((int*)bytes); bytes += sizeof(int); - NSString *actionName = [[NSString alloc] - initWithBytes:(void*)bytes length:len - encoding:NSUTF8StringEncoding]; - - SEL sel = NSSelectorFromString(actionName); - [NSApp sendAction:sel to:nil from:self]; - - [actionName release]; - } else if (ShowPopupMenuMsgID == msgid) { - NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; - - // The popup menu enters a modal loop so delay this call so that we - // don't block inside processInputQueue:. - [self performSelector:@selector(popupMenuWithAttributes:) - withObject:attrs - afterDelay:0]; - } else if (SetMouseShapeMsgID == msgid) { - const void *bytes = [data bytes]; - int shape = *((int*)bytes); - - [windowController setMouseShape:shape]; - } else if (AdjustLinespaceMsgID == msgid) { - const void *bytes = [data bytes]; - int linespace = *((int*)bytes); - - [windowController adjustLinespace:linespace]; - } else if (AdjustColumnspaceMsgID == msgid) { - const void *bytes = [data bytes]; - int columnspace = *((int*)bytes); - - [windowController adjustColumnspace:columnspace]; - } else if (ActivateMsgID == msgid) { - [NSApp activateIgnoringOtherApps:YES]; - [[windowController window] makeKeyAndOrderFront:self]; - } else if (SetServerNameMsgID == msgid) { - NSString *name = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - [self setServerName:name]; - [name release]; - } else if (EnterFullScreenMsgID == msgid) { - const void *bytes = [data bytes]; - int fuoptions = *((int*)bytes); bytes += sizeof(int); - int bg = *((int*)bytes); - NSColor *back = [NSColor colorWithArgbInt:bg]; - - [windowController enterFullScreen:fuoptions backgroundColor:back]; - } else if (LeaveFullScreenMsgID == msgid) { - [windowController leaveFullScreen]; - } else if (SetBuffersModifiedMsgID == msgid) { - const void *bytes = [data bytes]; - // state < 0 <-> some buffer modified - // state > 0 <-> current buffer modified - int state = *((int*)bytes); - - // NOTE: The window controller tracks whether current buffer is - // modified or not (and greys out the proxy icon as well as putting a - // dot in the red "close button" if necessary). The Vim controller - // tracks whether any buffer has been modified (used to decide whether - // to show a warning or not when quitting). - // - // TODO: Make 'hasModifiedBuffer' part of the Vim state? - [windowController setBufferModified:(state > 0)]; - hasModifiedBuffer = (state != 0); - } else if (SetPreEditPositionMsgID == msgid) { - const int *dim = (const int*)[data bytes]; - [[[windowController vimView] textView] setPreEditRow:dim[0] - column:dim[1]]; - } else if (EnableAntialiasMsgID == msgid) { - [[[windowController vimView] textView] setAntialias:YES]; - } else if (DisableAntialiasMsgID == msgid) { - [[[windowController vimView] textView] setAntialias:NO]; - } else if (EnableLigaturesMsgID == msgid) { - [[[windowController vimView] textView] setLigatures:YES]; - } else if (DisableLigaturesMsgID == msgid) { - [[[windowController vimView] textView] setLigatures:NO]; - } else if (EnableThinStrokesMsgID == msgid) { - [[[windowController vimView] textView] setThinStrokes:YES]; - } else if (DisableThinStrokesMsgID == msgid) { - [[[windowController vimView] textView] setThinStrokes:NO]; - } else if (SetVimStateMsgID == msgid) { - NSDictionary *dict = [NSDictionary dictionaryWithData:data]; - if (dict) { - [vimState release]; - vimState = [dict retain]; - } - } else if (CloseWindowMsgID == msgid) { - [self scheduleClose]; - } else if (SetFullScreenColorMsgID == msgid) { - const int *bg = (const int*)[data bytes]; - NSColor *color = [NSColor colorWithRgbInt:*bg]; - - [windowController setFullScreenBackgroundColor:color]; - } else if (ShowFindReplaceDialogMsgID == msgid) { - NSDictionary *dict = [NSDictionary dictionaryWithData:data]; - if (dict) { - [[MMFindReplaceController sharedInstance] - showWithText:[dict objectForKey:@"text"] - flags:[[dict objectForKey:@"flags"] intValue]]; - } - } else if (ActivateKeyScriptMsgID == msgid) { - [[[windowController vimView] textView] activateIm:YES]; - } else if (DeactivateKeyScriptMsgID == msgid) { - [[[windowController vimView] textView] activateIm:NO]; - } else if (EnableImControlMsgID == msgid) { - [[[windowController vimView] textView] setImControl:YES]; - } else if (DisableImControlMsgID == msgid) { - [[[windowController vimView] textView] setImControl:NO]; - } else if (BrowseForFileMsgID == msgid) { - NSDictionary *dict = [NSDictionary dictionaryWithData:data]; - if (dict) - [self handleBrowseForFile:dict]; - } else if (ShowDialogMsgID == msgid) { - [windowController runAfterWindowPresentedUsingBlock:^{ + } + break; + case SetWideFontMsgID: + { + const void *bytes = [data bytes]; + float size = *((float*)bytes); bytes += sizeof(float); + int len = *((int*)bytes); bytes += sizeof(int); + if (len > 0) { + NSString *name = [[NSString alloc] + initWithBytes:(void*)bytes length:len + encoding:NSUTF8StringEncoding]; + NSFont *font = [NSFont fontWithName:name size:size]; + [windowController setWideFont:font]; + + [name release]; + } else { + [windowController setWideFont:nil]; + } + } + break; + case SetDefaultColorsMsgID: + { + const void *bytes = [data bytes]; + unsigned bg = *((unsigned*)bytes); bytes += sizeof(unsigned); + unsigned fg = *((unsigned*)bytes); + NSColor *back = [NSColor colorWithArgbInt:bg]; + NSColor *fore = [NSColor colorWithRgbInt:fg]; + + [windowController setDefaultColorsBackground:back foreground:fore]; + } + break; + case ExecuteActionMsgID: + { + const void *bytes = [data bytes]; + int len = *((int*)bytes); bytes += sizeof(int); + NSString *actionName = [[NSString alloc] + initWithBytes:(void*)bytes length:len + encoding:NSUTF8StringEncoding]; + + SEL sel = NSSelectorFromString(actionName); + [NSApp sendAction:sel to:nil from:self]; + + [actionName release]; + } + break; + case ShowPopupMenuMsgID: + { + NSDictionary *attrs = [NSDictionary dictionaryWithData:data]; + + // The popup menu enters a modal loop so delay this call so that we + // don't block inside processInputQueue:. + [self performSelector:@selector(popupMenuWithAttributes:) + withObject:attrs + afterDelay:0]; + } + break; + case SetMouseShapeMsgID: + { + const void *bytes = [data bytes]; + int shape = *((int*)bytes); + + [windowController setMouseShape:shape]; + } + break; + case AdjustLinespaceMsgID: + { + const void *bytes = [data bytes]; + int linespace = *((int*)bytes); + + [windowController adjustLinespace:linespace]; + } + break; + case AdjustColumnspaceMsgID: + { + const void *bytes = [data bytes]; + int columnspace = *((int*)bytes); + + [windowController adjustColumnspace:columnspace]; + } + break; + case ActivateMsgID: + { + [NSApp activateIgnoringOtherApps:YES]; + [[windowController window] makeKeyAndOrderFront:self]; + } + break; + case SetServerNameMsgID: + { + NSString *name = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + [self setServerName:name]; + [name release]; + } + break; + case EnterFullScreenMsgID: + { + const void *bytes = [data bytes]; + int fuoptions = *((int*)bytes); bytes += sizeof(int); + int bg = *((int*)bytes); + NSColor *back = [NSColor colorWithArgbInt:bg]; + + [windowController enterFullScreen:fuoptions backgroundColor:back]; + } + break; + case LeaveFullScreenMsgID: + { + [windowController leaveFullScreen]; + } + break; + case SetBuffersModifiedMsgID: + { + const void *bytes = [data bytes]; + // state < 0 <-> some buffer modified + // state > 0 <-> current buffer modified + int state = *((int*)bytes); + + // NOTE: The window controller tracks whether current buffer is + // modified or not (and greys out the proxy icon as well as putting a + // dot in the red "close button" if necessary). The Vim controller + // tracks whether any buffer has been modified (used to decide whether + // to show a warning or not when quitting). + // + // TODO: Make 'hasModifiedBuffer' part of the Vim state? + [windowController setBufferModified:(state > 0)]; + hasModifiedBuffer = (state != 0); + } + break; + case SetPreEditPositionMsgID: + { + const int *dim = (const int*)[data bytes]; + [[[windowController vimView] textView] setPreEditRow:dim[0] + column:dim[1]]; + } + break; + case EnableAntialiasMsgID: + { + [[[windowController vimView] textView] setAntialias:YES]; + } + break; + case DisableAntialiasMsgID: + { + [[[windowController vimView] textView] setAntialias:NO]; + } + break; + case EnableLigaturesMsgID: + { + [[[windowController vimView] textView] setLigatures:YES]; + } + break; + case DisableLigaturesMsgID: + { + [[[windowController vimView] textView] setLigatures:NO]; + } + break; + case EnableThinStrokesMsgID: + { + [[[windowController vimView] textView] setThinStrokes:YES]; + } + break; + case DisableThinStrokesMsgID: + { + [[[windowController vimView] textView] setThinStrokes:NO]; + } + break; + case SetVimStateMsgID: + { + NSDictionary *dict = [NSDictionary dictionaryWithData:data]; + if (dict) { + [vimState release]; + vimState = [dict retain]; + } + } + break; + case CloseWindowMsgID: + { + [self scheduleClose]; + } + break; + case SetFullScreenColorMsgID: + { + const int *bg = (const int*)[data bytes]; + NSColor *color = [NSColor colorWithRgbInt:*bg]; + + [windowController setFullScreenBackgroundColor:color]; + } + break; + case ShowFindReplaceDialogMsgID: + { + NSDictionary *dict = [NSDictionary dictionaryWithData:data]; + if (dict) { + [[MMFindReplaceController sharedInstance] + showWithText:[dict objectForKey:@"text"] + flags:[[dict objectForKey:@"flags"] intValue]]; + } + } + break; + case ActivateKeyScriptMsgID: + { + [[[windowController vimView] textView] activateIm:YES]; + } + break; + case DeactivateKeyScriptMsgID: + { + [[[windowController vimView] textView] activateIm:NO]; + } + break; + case EnableImControlMsgID: + { + [[[windowController vimView] textView] setImControl:YES]; + } + break; + case DisableImControlMsgID: + { + [[[windowController vimView] textView] setImControl:NO]; + } + break; + case BrowseForFileMsgID: + { NSDictionary *dict = [NSDictionary dictionaryWithData:data]; if (dict) - [self handleShowDialog:dict]; - }]; - } else if (DeleteSignMsgID == msgid) { - NSDictionary *dict = [NSDictionary dictionaryWithData:data]; - if (dict) - [self handleDeleteSign:dict]; - } else if (ZoomMsgID == msgid) { - const void *bytes = [data bytes]; - int rows = *((int*)bytes); bytes += sizeof(int); - int cols = *((int*)bytes); bytes += sizeof(int); - int state = *((int*)bytes); - - [windowController zoomWithRows:rows - columns:cols - state:state]; - } else if (SetWindowPositionMsgID == msgid) { - const void *bytes = [data bytes]; - int x = *((int*)bytes); bytes += sizeof(int); - int y = *((int*)bytes); - - // NOTE: Vim measures Y-coordinates from top of screen. - NSRect frame = [[[windowController window] screen] frame]; - y = NSMaxY(frame) - y; - - [windowController setTopLeft:NSMakePoint(x,y)]; - } else if (SetTooltipMsgID == msgid) { - id textView = [[windowController vimView] textView]; - NSDictionary *dict = [NSDictionary dictionaryWithData:data]; - NSString *toolTip = dict ? [dict objectForKey:@"toolTip"] : nil; - if (toolTip && [toolTip length] > 0) - [textView setToolTipAtMousePoint:toolTip]; - else - [textView setToolTipAtMousePoint:nil]; - } else if (AddToMRUMsgID == msgid) { - NSDictionary *dict = [NSDictionary dictionaryWithData:data]; - NSArray *filenames = dict ? [dict objectForKey:@"filenames"] : nil; - if (filenames) - [[NSDocumentController sharedDocumentController] - noteNewRecentFilePaths:filenames]; - } else if (SetBackgroundOptionMsgID == msgid) { - const void *bytes = [data bytes]; - int dark = *((int*)bytes); - [windowController setBackgroundOption:dark]; - } else if (SetBlurRadiusMsgID == msgid) { - const void *bytes = [data bytes]; - int radius = *((int*)bytes); - [windowController setBlurRadius:radius]; - - // IMPORTANT: When adding a new message, make sure to update - // isUnsafeMessage() if necessary! - } else { - ASLogWarn(@"Unknown message received (msgid=%d)", msgid); + [self handleBrowseForFile:dict]; + } + break; + case ShowDialogMsgID: + { + [windowController runAfterWindowPresentedUsingBlock:^{ + NSDictionary *dict = [NSDictionary dictionaryWithData:data]; + if (dict) + [self handleShowDialog:dict]; + }]; + } + break; + case DeleteSignMsgID: + { + NSDictionary *dict = [NSDictionary dictionaryWithData:data]; + if (dict) + [self handleDeleteSign:dict]; + } + break; + case ZoomMsgID: + { + const void *bytes = [data bytes]; + int rows = *((int*)bytes); bytes += sizeof(int); + int cols = *((int*)bytes); bytes += sizeof(int); + int state = *((int*)bytes); + + [windowController zoomWithRows:rows + columns:cols + state:state]; + } + break; + case SetWindowPositionMsgID: + { + const void *bytes = [data bytes]; + int x = *((int*)bytes); bytes += sizeof(int); + int y = *((int*)bytes); + + // NOTE: Vim measures Y-coordinates from top of screen. + NSRect frame = [[[windowController window] screen] frame]; + y = NSMaxY(frame) - y; + + [windowController setTopLeft:NSMakePoint(x,y)]; + } + break; + case SetTooltipMsgID: + { + id textView = [[windowController vimView] textView]; + NSDictionary *dict = [NSDictionary dictionaryWithData:data]; + NSString *toolTip = dict ? [dict objectForKey:@"toolTip"] : nil; + if (toolTip && [toolTip length] > 0) + [textView setToolTipAtMousePoint:toolTip]; + else + [textView setToolTipAtMousePoint:nil]; + } + break; + case AddToMRUMsgID: + { + NSDictionary *dict = [NSDictionary dictionaryWithData:data]; + NSArray *filenames = dict ? [dict objectForKey:@"filenames"] : nil; + if (filenames) + [[NSDocumentController sharedDocumentController] + noteNewRecentFilePaths:filenames]; + } + break; + case SetBackgroundOptionMsgID: + { + const void *bytes = [data bytes]; + int dark = *((int*)bytes); + [windowController setBackgroundOption:dark]; + } + break; + case SetBlurRadiusMsgID: + { + const void *bytes = [data bytes]; + int radius = *((int*)bytes); + [windowController setBlurRadius:radius]; + } + break; + + case ShowDefinitionMsgID: + { + const void* bytes = [data bytes]; + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + NSUInteger len = *((NSUInteger*)bytes); bytes += sizeof(NSUInteger); + if (len > 0) { + NSString *text = [[[NSString alloc] initWithBytes:(void*)bytes + length:len + encoding:NSUTF8StringEncoding] autorelease]; + + // Convert from 1-indexed (Vim-style) to 0-indexed. + row -= 1; + col -= 1; + + MMTextView *view = [[windowController vimView] textView]; + [view showDefinitionForCustomString:text row:row col:col]; + } + } + break; + + // IMPORTANT: When adding a new message, make sure to update + // isUnsafeMessage() if necessary! + default: + { + ASLogWarn(@"Unknown message received (msgid=%d)", msgid); + } } } diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index e3a99baed6..cd5174db87 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -308,6 +308,7 @@ extern const char * const MMVimMsgIDStrings[]; MSG(DisableLigaturesMsgID) \ MSG(EnableThinStrokesMsgID) \ MSG(DisableThinStrokesMsgID) \ + MSG(ShowDefinitionMsgID) \ MSG(LastMsgID) \ enum { diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index 24bfae2086..e34a2dfe3b 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -2534,6 +2534,94 @@ [[MMBackend sharedInstance] setBackground:dark]; } +#pragma region MacVim builtin functions +#pragma mark MacVim builtin functions + +/// Implementation of showdefinition() +void f_showdefinition(typval_T *argvars, typval_T *rettv UNUSED) +{ + if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + return; + + char_u *lookup_text = tv_get_string(&argvars[0]); + + varnumber_T screen_row = -1; + varnumber_T screen_col = -1; + + if (argvars[1].v_type == VAR_DICT) { + // Retrieve the optional row/col from the caller. Note that this is + // designed so that the input object could just be the output of + // screenpos(). + dict_T *d = argvars[1].vval.v_dict; + if (d != NULL) { + screen_row = dict_get_number_def(d, "row", -1); + screen_col = dict_get_number_def(d, "col", -1); + } + } + + if (screen_row <= 0 || screen_col <= 0) { + // row/col are optional parameters, so if not given we just use the + // cursor position. + // We are essentially doing the following: + // var curpos = getcurpos() + // var screenpos = screenpos(win_getid(), curpos[1], curpos[2]) + // showDefinition(text, screenpos['row'], screenpos['col']) + // + // Note that we could either take screenpos['cursorcol'] or + // screenpos['col']. Both could make sense in some situations, but just + // for consistency with how this function is used, we just use 'col'. + // (It's consistent because this function is designed so that you can + // just pass the output of screenpos() directly into the 2nd argument). + varnumber_T lnum = 0, col = 0; + { + typval_T args[1] = { {VAR_UNKNOWN} }; + typval_T lrettv; + + f_getcurpos(args, &lrettv); + if (lrettv.v_type == VAR_LIST) { + lnum = list_find(lrettv.vval.v_list, 1)->li_tv.vval.v_number; + col = list_find(lrettv.vval.v_list, 2)->li_tv.vval.v_number; + list_unref(lrettv.vval.v_list); + } + } + { + typval_T arg_winid; + arg_winid.v_type = VAR_NUMBER; + arg_winid.vval.v_number = curwin->w_id; + + typval_T arg_lnum; + arg_lnum.v_type = VAR_NUMBER; + arg_lnum.vval.v_number = lnum; + + typval_T arg_col; + arg_col.v_type = VAR_NUMBER; + arg_col.vval.v_number = col; + + typval_T args[4] = { + arg_winid, + arg_lnum, + arg_col, + {VAR_UNKNOWN} + }; + typval_T lrettv; + + f_screenpos(args, &lrettv); + + screen_row = dict_get_number_def(lrettv.vval.v_dict, "row", -1); + screen_col = dict_get_number_def(lrettv.vval.v_dict, "col", -1); + + dict_unref(lrettv.vval.v_dict); + } + } + + NSString *lookup_text_str = [NSString stringWithVimString:lookup_text]; + [[MMBackend sharedInstance] showDefinition:lookup_text_str + row:screen_row + col:screen_col]; +} + +#pragma endregion + // -- Netbeans Integration Support ------------------------------------------- diff --git a/src/MacVim/scripts/extract-specific-localised-strings.swift b/src/MacVim/scripts/extract-specific-localised-strings.swift index e859973f1d..43dd0fd960 100755 --- a/src/MacVim/scripts/extract-specific-localised-strings.swift +++ b/src/MacVim/scripts/extract-specific-localised-strings.swift @@ -185,6 +185,7 @@ let neededLocalisations_vim = [ NeededLocalisation(targetKey: "Show\\ Previous\\ Tab", appleKey: "Show Previous Tab", glossaryFilename: "AppKit"), NeededLocalisation(targetKey: "Bring\\ All\\ to\\ Front", appleKey: "Bring All to Front", glossaryFilename: "AppKit"), NeededLocalisation(targetKey: "Release\\ Notes", appleKey: "Release Notes (WFContentItemPropertyName)", glossaryFilename: "Shortcuts"), + NeededLocalisation(targetKey: "Look\\ Up", appleKey: "Look Up", glossaryFilename: "iBooks"), ] var neededLocalisations = neededLocalisations_mainmenu_xib diff --git a/src/evalfunc.c b/src/evalfunc.c index d56b1ea570..67070f2325 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -66,7 +66,6 @@ static void f_getenv(typval_T *argvars, typval_T *rettv); static void f_getfontname(typval_T *argvars, typval_T *rettv); static void f_getjumplist(typval_T *argvars, typval_T *rettv); static void f_getpid(typval_T *argvars, typval_T *rettv); -static void f_getcurpos(typval_T *argvars, typval_T *rettv); static void f_getcursorcharpos(typval_T *argvars, typval_T *rettv); static void f_getpos(typval_T *argvars, typval_T *rettv); static void f_getreg(typval_T *argvars, typval_T *rettv); @@ -2473,6 +2472,10 @@ static funcentry_T global_functions[] = ret_string, f_shellescape}, {"shiftwidth", 0, 1, FEARG_1, arg1_number, ret_number, f_shiftwidth}, +#ifdef FEAT_GUI_MACVIM + {"showdefinition", 1, 2, FEARG_1, arg2_string_dict, + ret_void, f_showdefinition}, +#endif {"sign_define", 1, 2, FEARG_1, arg2_string_or_list_dict, ret_any, SIGN_FUNC(f_sign_define)}, {"sign_getdefined", 0, 1, FEARG_1, arg1_string, @@ -5136,7 +5139,7 @@ f_getpid(typval_T *argvars UNUSED, typval_T *rettv) /* * "getcurpos()" function */ - static void + void f_getcurpos(typval_T *argvars, typval_T *rettv) { if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL) diff --git a/src/proto/evalfunc.pro b/src/proto/evalfunc.pro index da1c324119..d8738b7408 100644 --- a/src/proto/evalfunc.pro +++ b/src/proto/evalfunc.pro @@ -27,4 +27,8 @@ void f_len(typval_T *argvars, typval_T *rettv); void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv); void range_list_materialize(list_T *list); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit); + +// MacVim only +void f_getcurpos(typval_T *argvars, typval_T *rettv); + /* vim: set ft=c : */ diff --git a/src/proto/gui_macvim.pro b/src/proto/gui_macvim.pro index e25772e473..22608fc7f5 100644 --- a/src/proto/gui_macvim.pro +++ b/src/proto/gui_macvim.pro @@ -134,4 +134,6 @@ void gui_mch_destroy_sign(void *sign); void *gui_macvim_new_autoreleasepool(); void gui_macvim_release_autoreleasepool(void *pool); +void f_showdefinition(typval_T *argvars, typval_T *rettv); + void netbeans_draw_multisign_indicator(int row);