### Install local release Source: https://github.com/qvacua/vimr/blob/master/README.md Helper script to build and install the application into the /Applications directory. ```bash ./bin/build_and_install_local_release.sh ``` -------------------------------- ### Build VimR from source Source: https://github.com/qvacua/vimr/blob/master/README.md Commands to initialize submodules, install dependencies, and execute the build script. ```bash git submodule update --init xcode-select --install # install the Xcode command line tools, if you haven't already brew bundle # install dependencies, e.g., build tools for Neovim clean=true notarize=false trust_plugins=true ./bin/build_vimr.sh ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/qvacua/vimr/blob/master/bin/README.md Install all required Python packages listed in the requirements file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Build VimR from Source Source: https://context7.com/qvacua/vimr/llms.txt Shell commands to clone the repository, install dependencies, and execute the build script. ```bash # Clone and setup git clone https://github.com/qvacua/vimr.git cd vimr git submodule update --init # Install dependencies xcode-select --install brew bundle # Build with pre-built Neovim (recommended) clean=true notarize=false trust_plugins=true ./bin/build_vimr.sh ``` -------------------------------- ### Configure Git Diff Tool for VimR Source: https://github.com/qvacua/vimr/wiki/Home Example configuration for .gitconfig to use VimR as the difftool for Git. This setup uses the 'vimr --wait --nvim -d' command to open diffs in VimR. ```gitconfig [difftool "vimrdiff"] cmd = vimr --wait --nvim -d $LOCAL $REMOTE [diff] tool = vimrdiff ``` -------------------------------- ### Configure Git difftool with VimR Source: https://github.com/qvacua/vimr/blob/master/resources/release-notes.md Configure your Git difftool to use VimR for diffing. This setup allows VimR to be used as a git difftool, leveraging its diff mode. ```gitconfig [difftool "vimrdiff"] cmd = vimr --wait --nvim -d $LOCAL $REMOTE [diff] tool = vimrdiff ``` -------------------------------- ### Build Neovim Server Source: https://github.com/qvacua/vimr/blob/master/DEVELOP.md Commands to download or build the Neovim server for development purposes. ```bash clean=true for_dev=false ./bin/build_nvimserver.sh ``` ```bash clean=true for_dev=true ./bin/build_nvimserver.sh ``` -------------------------------- ### VimR Command Line Tool Help Source: https://github.com/qvacua/vimr/wiki/Home Displays help information for the 'vimr' command-line tool, outlining its usage and available arguments for opening files and controlling Neovim instances. ```bash $ vimr --help usage: vimr [-h] [--dry-run] [--cwd CWD] [--line LINE] [--wait] [--nvim] [--cur-env | -n | -s] [file [file ...]] Open files in VimR: By default all files are open in tabs in the front most window or in a new window if there is none. The working directory will be set to the current directory. positional arguments: file optional arguments: -h, --help show this help message and exit --dry-run Just print the 'open' command. --cwd CWD Set the working directory. --line LINE Go to line --wait This command line tool will exit when the corresponding UI window is closed. --nvim All arguments except --cur-env, --line, --dry-run and --wait will be passed over to the (new) nvim instance in a new UI window. --cur-env Use the current environment variables when launching the background neovim process. All files will be opened in a new window. -n Open files in tabs in a new window. -s Open files in separate windows. ``` -------------------------------- ### Configure Ignore Patterns in .vimr_rc Source: https://github.com/qvacua/vimr/wiki/VimR-MacVim Define file and folder ignore patterns for the Open Quickly action by creating a .vimr_rc file in the home directory. ```text open.quickly.ignore.patterns = */.git, */.hg, .DS_Store, */target, */*.xcodeproj ``` -------------------------------- ### Generate API Swift File Source: https://github.com/qvacua/vimr/blob/master/NvimApi/README.md Run this script after checking out the correct Git reference to generate the API Swift file. Ensure you are on the correct branch, such as 'develop' or 'update-neovim'. ```bash ./bin/generate_sources.sh ``` -------------------------------- ### Create and Configure NvimView Source: https://context7.com/qvacua/vimr/llms.txt Instantiate NvimView with custom configurations for embedding Neovim in a Cocoa application. Set appearance properties and add it to the view hierarchy. ```swift import NvimView // Create NvimView with configuration let config = NvimView.Config( usesCustomTabBar: true, useInteractiveZsh: false, cwd: URL(fileURLWithPath: NSHomeDirectory()), nvimBinary: "/opt/homebrew/bin/nvim", // or empty for bundled nvim nvimArgs: nil, additionalEnvs: ["TERM": "xterm-256color"], sourceFiles: [] // Additional vim files to source ) let nvimView = NvimView(frame: NSRect(x: 0, y: 0, width: 800, height: 600), config: config) // Set delegate to receive events nvimView.delegate = self // Configure appearance nvimView.font = NSFont(name: "JetBrains Mono", size: 14) ?? NvimView.defaultFont nvimView.linespacing = 1.2 nvimView.characterspacing = 1.0 nvimView.usesLigatures = true nvimView.fontSmoothing = .systemSetting nvimView.isLeftOptionMeta = true // Use Option as Meta key // Add to window window.contentView?.addSubview(nvimView) ``` -------------------------------- ### IDE-like Layout Management with Workspace Source: https://context7.com/qvacua/vimr/llms.txt Workspace facilitates IDE-like layouts with dockable tool panels. Configure themes, add tools to specific locations, and manage their visibility and movement. Implement the WorkspaceDelegate protocol to respond to layout events like resizing. ```swift import Workspace // Create workspace with main content view let mainEditor = NSTextView() let workspace = Workspace( mainView: mainEditor, config: Workspace.Config(mainViewMinimumSize: CGSize(width: 400, height: 300)) ) // Configure theme workspace.theme = Workspace.Theme( foreground: .textColor, background: .textBackgroundColor, separator: .separatorColor, barBackground: .windowBackgroundColor, barFocusRing: .selectedControlColor, barButtonBackground: .clear, barButtonHighlight: .separatorColor, toolbarForeground: .darkGray, toolbarBackground: NSColor(red: 0.9, green: 0.93, blue: 1.0, alpha: 1) ) // Create tool panels let fileBrowserView = FileBrowserView() let fileBrowserTool = WorkspaceTool( title: "Files", view: fileBrowserView, minimumDimension: 150, isWithinMinimumDimension: true ) let bufferListView = BufferListView() let bufferListTool = WorkspaceTool( title: "Buffers", view: bufferListView, minimumDimension: 100, isWithinMinimumDimension: true ) let previewView = MarkdownPreviewView() let previewTool = WorkspaceTool( title: "Preview", view: previewView, minimumDimension: 200, isWithinMinimumDimension: true ) // Add tools to workspace bars workspace.append(tool: fileBrowserTool, location: .left) workspace.append(tool: bufferListTool, location: .left) workspace.append(tool: previewTool, location: .right) // Move tools between bars workspace.move(tool: previewTool, to: .bottom) // Toggle visibility workspace.toggleAllTools() workspace.hideAllTools() workspace.showAllTools() // Toggle tool buttons visibility workspace.toggleToolButtons() // Set delegate for resize events workspace.delegate = self // WorkspaceDelegate implementation extension MyController: WorkspaceDelegate { func resizeWillStart(workspace: Workspace, tool: WorkspaceTool?) { // Pause expensive operations during resize } func resizeDidEnd(workspace: Workspace, tool: WorkspaceTool?) { // Resume operations } func toggled(tool: WorkspaceTool) { print("Tool toggled: \(tool.title)") } func moved(tool: WorkspaceTool) { print("Tool moved: \(tool.title)") } } ``` -------------------------------- ### Build VimR from source Source: https://context7.com/qvacua/vimr/llms.txt Commands to compile Neovim and VimR locally for development purposes. ```bash clean=true for_dev=true ./bin/build_nvimserver.sh clean=true notarize=false trust_plugins=true ./bin/build_vimr.sh ``` -------------------------------- ### Execute Async Neovim API Commands Source: https://context7.com/qvacua/vimr/llms.txt Interact with Neovim via MessagePack-RPC using NvimApi. Requires setting up pipes and attaching a UI before executing commands. ```swift import NvimApi import Foundation // Initialize and connect to Neovim let api = NvimApi() // Start Neovim process with pipes let process = Process() process.executableURL = URL(fileURLWithPath: "/opt/homebrew/bin/nvim") process.arguments = ["--embed"] let inPipe = Pipe() let outPipe = Pipe() let errorPipe = Pipe() process.standardInput = inPipe process.standardOutput = outPipe process.standardError = errorPipe try process.run() // Connect API to the pipes try await api.run(inPipe: inPipe, outPipe: outPipe, errorPipe: errorPipe) // Attach UI (required for most operations) try await api.nvimUiAttach(width: 80, height: 24, options: [ "ext_linegrid": true, "rgb": true ]).get() // Execute Vim commands try await api.nvimCommand(command: "set number").get() try await api.nvimCommand(command: "colorscheme desert").get() // Execute Vim script and capture output let result = try await api.nvimExec2( src: "echo 'Hello from Neovim'", opts: ["output": true] ).get() print(result["output"]?.stringValue ?? "") // Buffer operations let currentBuf = try await api.nvimGetCurrentBuf().get() let lineCount = try await api.nvimBufLineCount(buffer: currentBuf).get() print("Buffer has \(lineCount) lines") // Get/set buffer lines let lines = try await api.nvimBufGetLines( buffer: currentBuf, start: 0, end: 10, strict_indexing: false ).get() try await api.nvimBufSetLines( buffer: currentBuf, start: 0, end: 0, strict_indexing: false, replacement: ["// New line at top"] ).get() // Send input keys try await api.nvimInput(keys: "").get() try await api.nvimInput(keys: "gg").get() // Execute Lua code let luaResult = try await api.nvimExecLua(code: """ local buffers = vim.fn.getbufinfo({bufmodified = true}) return #buffers """, args: []).get() print("Modified buffers: \(luaResult.intValue ?? 0)") // Window operations let currentWin = try await api.nvimGetCurrentWin().get() try await api.nvimWinSetCursor(window: currentWin, pos: [10, 5]).get() // Get mode information let mode = try await api.nvimGetMode().get() let isBlocked = mode["blocking"]?.boolValue ?? false let modeName = mode["mode"]?.stringValue ?? "" print("Mode: \(modeName), Blocked: \(isBlocked)") // Clean up try await api.nvimUiDetach().get() try await api.nvimCommand(command: "qa!").get() await api.stop() ``` -------------------------------- ### Apply VimR Specific Settings Source: https://github.com/qvacua/vimr/wiki/Home Use the 'g:gui_vimr' flag in init.vim to apply settings only when running VimR. Alternatively, place VimR-specific settings in ginit.vim. ```VimL if exists("g:gui_vimr") " Here goes some VimR specific settings like color xyz endif ``` -------------------------------- ### Build and Publish VimR Release Source: https://github.com/qvacua/vimr/blob/master/DEVELOP.md Commands to build and publish a release using a specification file. ```bash release_spec_file=....sh \ ./bin/build_release.sh ``` ```bash create_gh_release=true upload=true update_appcast=true \ release_spec_file=....sh \ ./bin/publish_release.sh ``` -------------------------------- ### Handle NvimViewDelegate Events Source: https://context7.com/qvacua/vimr/llms.txt Implement the NvimViewDelegate protocol to respond to various events from the Neovim instance. This includes Neovim readiness, process termination, buffer changes, and UI updates. ```swift import NvimView @MainActor class MyViewController: NSViewController, NvimViewDelegate { func isMenuItemKeyEquivalent(_ event: NSEvent) -> Bool { // Return true if the event should be handled as a menu shortcut return false } func nextEvent(_ event: NvimView.Event) { switch event { case .nvimReady: print("Neovim is ready for commands") case .neoVimStopped: print("Neovim process terminated") case .setTitle(let title): window?.title = title case .setDirtyStatus(let isDirty): window?.isDocumentEdited = isDirty case .cwdChanged: print("Working directory changed to: \(nvimView.cwd)") case .bufferListChanged: Task { await updateBufferList() } case .newCurrentBuffer(let buffer): print("Current buffer: \(buffer.url?.path ?? "untitled")") case .colorschemeChanged(let theme): updateUIColors(with: theme) case .guifontChanged(let font): print("Font changed to: \(font.fontName)") case .warning(.cannotCloseLastTab): showAlert("Cannot close the last tab") case .warning(.noWriteSinceLastChange): showAlert("No write since last change") case .ipcBecameInvalid(let description): showError("IPC Error: \(description)") case .rpcEvent(let params): handleRpcEvent(params) default: break } } } ``` -------------------------------- ### Perform NvimView Buffer and Tab Operations Source: https://context7.com/qvacua/vimr/llms.txt Use these async methods to manage files, buffers, and tabs within a Neovim instance. Requires an initialized NvimView instance. ```swift import NvimView // Opening files Task { // Open files in new tabs let urls = [ URL(fileURLWithPath: "/path/to/file1.swift"), URL(fileURLWithPath: "/path/to/file2.swift") ] await nvimView.openInNewTab(urls: urls) // Open in current tab (replaces current buffer) await nvimView.openInCurrentTab(url: URL(fileURLWithPath: "/path/to/file.txt")) // Open in splits await nvimView.openInHorizontalSplit(urls: urls) await nvimView.openInVerticalSplit(urls: urls) // Smart open - reuses existing buffer if already open await nvimView.open(urls: urls) } // Buffer operations Task { // Get current buffer info if let buffer = await nvimView.currentBuffer() { print("URL: \(buffer.url?.path ?? "none")") print("Is dirty: \(buffer.isDirty)") print("Is listed: \(buffer.isListed)") print("Buffer type: \(buffer.type)") } // Get all buffers if let buffers = await nvimView.allBuffers() { for buf in buffers where buf.isListed { print("Buffer: \(buf.url?.lastPathComponent ?? "untitled")") } } // Select a specific buffer if let targetBuffer = buffers?.first(where: { $0.url?.lastPathComponent == "main.swift" }) { await nvimView.select(buffer: targetBuffer) } // Check for unsaved changes let hasDirty = await nvimView.hasDirtyBuffers() if hasDirty { showSavePrompt() } } // Tab operations Task { // Get all tabs with their windows and buffers if let tabs = await nvimView.allTabs() { for tab in tabs { print("Tab (current: \(tab.isCurrent)):") for window in tab.windows { print(" Window: \(window.buffer.url?.lastPathComponent ?? "untitled")") } } } // Create new tab await nvimView.newTab() // Close current tab await nvimView.closeCurrentTab() // Save and close operations await nvimView.saveCurrentTab() await nvimView.saveCurrentTab(url: URL(fileURLWithPath: "/new/path/file.txt")) await nvimView.closeCurrentTabWithoutSaving() // Navigate to line await nvimView.goTo(line: 42) } ``` -------------------------------- ### Perform File System Operations with FileUtils Source: https://context7.com/qvacua/vimr/llms.txt Provides utilities for path manipulation, file existence checks, and retrieving system icons for files. ```swift import Commons // Get common parent of multiple files let files = [ URL(fileURLWithPath: "/Users/dev/project/src/main.swift"), URL(fileURLWithPath: "/Users/dev/project/src/utils/helpers.swift"), URL(fileURLWithPath: "/Users/dev/project/tests/MainTests.swift") ] let commonParent = FileUtils.commonParent(of: files) print("Common parent: \(commonParent.path)") // /Users/dev/project // Get direct descendants of directory let entries = FileUtils.directDescendants(of: URL(fileURLWithPath: "/Users/dev/project")) for entry in entries { print(entry.lastPathComponent) } // Check file existence let exists = FileUtils.fileExists(at: URL(fileURLWithPath: "/path/to/file.txt")) // Get file icons for display let fileUrl = URL(fileURLWithPath: "/path/to/document.pdf") if let icon = FileUtils.icon(forUrl: fileUrl) { imageView.image = icon // 16x16 NSImage } // Get icon for file type let swiftIcon = FileUtils.icon(forType: "public.swift-source") // Utility paths let home = FileUtils.userHomeUrl let temp = FileUtils.tempDir() ``` -------------------------------- ### Tag Neovim Release Source: https://github.com/qvacua/vimr/blob/master/DEVELOP.md Command to tag and push a new Neovim version. ```bash version=neovim-vX.Y.Z-$(date "+%Y%m%d.%H%M%S"); git tag -a "${version}" -m "${version}"; git push origin "${version}" ``` -------------------------------- ### Generate Neovim Sources Source: https://github.com/qvacua/vimr/blob/master/DEVELOP.md Commands to update Neovim and generate necessary source files. ```bash clean=true use_committed_nvim=true ./bin/generate_sources.sh ``` -------------------------------- ### NvimViewDelegate - Handling Neovim Events Source: https://context7.com/qvacua/vimr/llms.txt This section details the `NvimViewDelegate` protocol, which allows your application to receive and respond to various events originating from the embedded Neovim instance. It covers common events like Neovim readiness, buffer changes, title updates, and error handling. ```APIDOC ## NvimViewDelegate - Handling Neovim Events ### Description Implement the `NvimViewDelegate` protocol to handle events emitted by the `NvimView`. This delegate provides callbacks for various Neovim states and actions, enabling your application to react accordingly. ### Method Event Handling ### Endpoint N/A (This is a protocol usage example) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift import NvimView @MainActor class MyViewController: NSViewController, NvimViewDelegate { func isMenuItemKeyEquivalent(_ event: NSEvent) -> Bool { // Return true if the event should be handled as a menu shortcut return false } func nextEvent(_ event: NvimView.Event) { switch event { case .nvimReady: print("Neovim is ready for commands") case .neoVimStopped: print("Neovim process terminated") case .setTitle(let title): window?.title = title case .setDirtyStatus(let isDirty): window?.isDocumentEdited = isDirty case .cwdChanged: print("Working directory changed to: \(nvimView.cwd)") case .bufferListChanged: Task { await updateBufferList() } case .newCurrentBuffer(let buffer): print("Current buffer: \(buffer.url?.path ?? "untitled")") case .colorschemeChanged(let theme): updateUIColors(with: theme) case .guifontChanged(let font): print("Font changed to: \(font.fontName)") case .warning(.cannotCloseLastTab): showAlert("Cannot close the last tab") case .warning(.noWriteSinceLastChange): showAlert("No write since last change") case .ipcBecameInvalid(let description): showError("IPC Error: \(description)") case .rpcEvent(let params): handleRpcEvent(params) default: break } } } ``` ### Response #### Success Response (200) N/A (This is a client-side code example) #### Response Example None ``` -------------------------------- ### NvimView - Embedding Neovim Source: https://context7.com/qvacua/vimr/llms.txt This section demonstrates how to create and configure an NvimView instance to embed Neovim within a Cocoa application. It covers initialization with custom configurations, setting appearance properties, and adding the view to the application's window. ```APIDOC ## NvimView - Embedding Neovim in Cocoa Applications ### Description This code snippet shows how to initialize and configure the `NvimView` class, which embeds a Neovim instance into a Cocoa application. It includes setting up custom configurations, appearance, and integrating the view into the application's window. ### Method Initialization and Configuration ### Endpoint N/A (This is a class usage example) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift import NvimView // Create NvimView with configuration let config = NvimView.Config( usesCustomTabBar: true, useInteractiveZsh: false, cwd: URL(fileURLWithPath: NSHomeDirectory()), nvimBinary: "/opt/homebrew/bin/nvim", // or empty for bundled nvim nvimArgs: nil, additionalEnvs: ["TERM": "xterm-256color"], sourceFiles: [] // Additional vim files to source ) let nvimView = NvimView(frame: NSRect(x: 0, y: 0, width: 800, height: 600), config: config) // Set delegate to receive events nvimView.delegate = self // Configure appearance nvimView.font = NSFont(name: "JetBrains Mono", size: 14) ?? NvimView.defaultFont nvimView.linespacing = 1.2 nvimView.characterspacing = 1.0 nvimView.usesLigatures = true nvimView.fontSmoothing = .systemSetting nvimView.isLeftOptionMeta = true // Use Option as Meta key // Add to window window.contentView?.addSubview(nvimView) ``` ### Response #### Success Response (200) N/A (This is a client-side code example) #### Response Example None ``` -------------------------------- ### VimR DirDiff Integration Commands Source: https://github.com/qvacua/vimr/wiki/How-to-use-VimR-as-git-difftool-(with-DirDiff.vim) Extend the temporary maximized window command to integrate with DirDiff.vim. This includes a small delay and selecting the first file to adjust panes. Place this in `~/.config/nvim/ginit.vim`. ```viml function! s:VimRTempMaxWin() abort VimRMakeSessionTemporary " The tools, tool buttons and window settings are not persisted VimRHideTools VimRMaximizeWindow endfunction command! -nargs=0 VimRTempMaxWin call s:VimRTempMaxWin() function! s:VimRDifDiff() abort VimRTempMaxWin sleep 500m " Yes, ugly, but I could not find a better solution. normal o " Select the first file (again) to resize the panes. endfunction command! -nargs=0 VimRDirDiff call s:VimRDirDiff() ``` -------------------------------- ### Verify Python Virtual Environment Path Source: https://github.com/qvacua/vimr/blob/master/bin/README.md Use this command to confirm that the active Python interpreter is correctly pointing to the project-specific virtual environment. ```bash pyenv which python /${HOME}/.pyenv/versions/com.qvacua.VimR.bin/bin/python ``` -------------------------------- ### Modify Jenkins Startup Script Source: https://github.com/qvacua/vimr/blob/master/ci/README.md Add '-Dhudson.plugins.git.GitSCM.ALLOW_LOCAL_CHECKOUT=true' to the Jenkins startup script to enable local Git repository checkouts. This is useful for testing with local repositories. ```bash #!/bin/bash export JAVA_HOME="${JAVA_HOME:-/opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home}" exec "${JAVA_HOME}/bin/java" "-Dhudson.plugins.git.GitSCM.ALLOW_LOCAL_CHECKOUT=true" "-jar" "/opt/homebrew/Cellar/jenkins/2.435/libexec/jenkins.war" "$@" ``` -------------------------------- ### Synchronous Neovim API Calls with NvimApiSync Source: https://context7.com/qvacua/vimr/llms.txt Use NvimApiSync for immediate Neovim API responses, essential for UI handlers. Connect via Unix socket and execute commands, retrieve buffer information, or run Lua code synchronously. Ensure Neovim is running with a socket enabled before connecting. ```swift import NvimApi let apiSync = NvimApiSync() // Connect via Unix socket (after Neovim is running) try apiSync.run(socketPath: "/tmp/nvim-socket.sock") // Synchronous command execution let result = apiSync.nvimCommand(command: "echo 'sync call'") switch result { case .success: print("Command executed") case .failure(let error): print("Error: \(error)") } // Get current buffer synchronously switch apiSync.nvimGetCurrentBuf() { case .success(let buffer): print("Current buffer handle: \(buffer.handle)") case .failure(let error): print("Failed: \(error)") } // Execute Lua synchronously let luaResult = apiSync.nvimExecLua(code: """ local info = vim.fn.getbufinfo(...)[1] return { name = info.name, changed = info.changed, listed = info.listed } """, args: [MessagePackValue(bufferHandle)]) // Set current directory apiSync.nvimSetCurrentDir(dir: "/new/working/directory").cauterize() // Tab operations apiSync.nvimCommand(command: "tabclose 2").cauterize() apiSync.nvimSetCurrentTabpage(tabpage: NvimApi.Tabpage(1)).cauterize() // Stop the connection apiSync.stop() ``` -------------------------------- ### List of Menu Item Identifiers Source: https://github.com/qvacua/vimr/wiki/VimR-MacVim A comprehensive list of available menu item identifiers that can be mapped in the configuration file. ```text global.keybinding.menuitem.file.new global.keybinding.menuitem.file.new-tab global.keybinding.menuitem.file.open global.keybinding.menuitem.file.open-in-tab global.keybinding.menuitem.file.open-quickly global.keybinding.menuitem.file.close global.keybinding.menuitem.file.save global.keybinding.menuitem.file.save-as global.keybinding.menuitem.file.revert-to-saved global.keybinding.menuitem.edit.undo global.keybinding.menuitem.edit.redo global.keybinding.menuitem.edit.cut global.keybinding.menuitem.edit.copy global.keybinding.menuitem.edit.paste global.keybinding.menuitem.edit.delete global.keybinding.menuitem.edit.select-all global.keybinding.menuitem.view.focus-file-browser global.keybinding.menuitem.view.focus-text-area global.keybinding.menuitem.view.show-file-browser global.keybinding.menuitem.view.put-file-browser-on-right global.keybinding.menuitem.view.show-status-bar global.keybinding.menuitem.view.font.show-fonts global.keybinding.menuitem.view.font.bigger global.keybinding.menuitem.view.font.smaller global.keybinding.menuitem.view.enter-full-screen global.keybinding.menuitem.navigate.show-folders-first global.keybinding.menuitem.navigate.show-hidden-files global.keybinding.menuitem.navigate.sync-vim-pwd global.keybinding.menuitem.preview.show-preview global.keybinding.menuitem.preview.refresh global.keybinding.menuitem.window.minimize global.keybinding.menuitem.window.zoom global.keybinding.menuitem.window.select-next-tab global.keybinding.menuitem.window.select-previous-tab global.keybinding.menuitem.window.bring-all-to-front global.keybinding.menuitem.help.vimr-help ``` -------------------------------- ### Set New VimR Versions Source: https://github.com/qvacua/vimr/blob/master/DEVELOP.md Commands to set the version for either snapshot or release builds. ```bash is_snapshot=true ./bin/set_new_versions.sh # for snapshot or is_snapshot=false marketing_version=0.38.3 ./bin/set_new_versions.sh # for release ``` -------------------------------- ### Enable Debug Menu Source: https://github.com/qvacua/vimr/blob/master/DEVELOP.md Command to enable the debug menu in a Release build of VimR. ```bash defaults write com.qvacua.VimR enable-debug-menu 1 ``` -------------------------------- ### Git Configuration for VimR Difftool Source: https://github.com/qvacua/vimr/wiki/How-to-use-VimR-as-git-difftool-(with-DirDiff.vim) Configure git to use VimR as the difftool, invoking the temporary maximized window command. This configuration should be placed in `~/.gitconfig`. ```gitconfig [difftool "vimrdiff"] cmd = vimr --wait --nvim '+au GUIEnter * execute "DirDiff" argv(0) argv(1)' '+au GUIEnter * VimRTempMaxWin' $LOCAL $REMOTE [diff] tool = vimrdiff ``` -------------------------------- ### Markdown Preview Scrolling and Navigation Logic Source: https://github.com/qvacua/vimr/blob/master/VimR/VimR/markdown/template.html Handles viewport detection, scroll event throttling, and element positioning for Markdown previews. Requires elements to have a data-sourcepos attribute. ```javascript {{ css-overrides }} // Scrolling const sourceposRegex = /(\d+):(\d+)-(\d+):(\d+)/; let suppressNextScrollEvent = false; function isTopLeftInsideViewport(el) { const rect = el.getBoundingClientRect(); return rect.top >= 0 && rect.left >= 0; } function isElementVisibleInViewport(el) { const rect = el.getBoundingClientRect(); return ( ((rect.top >= 0 && window.innerHeight - rect.top >= 0) || (rect.top < 0 && rect.bottom > 0)) && ((rect.left >= 0 && window.innerWidth - rect.left >= 0) || (rect.left < 0 && rect.right > 0)) ); } function positionOfMarkdownElement(element) { const regexResult = element.dataset.sourcepos.match(sourceposRegex); if (regexResult.length !== 5) { return null; } return { lineBegin: parseInt(regexResult[1], 10), columnBegin: parseInt(regexResult[2], 10), lineEnd: parseInt(regexResult[3], 10), columnEnd: parseInt(regexResult[4], 10) }; } function toArray(nodeList) { return Array.prototype.slice.call(nodeList) } function currentTopMarkdownElement() { const mdElements = toArray(document.querySelectorAll("[data-sourcepos]")); return mdElements.find(isTopLeftInsideViewport) || mdElements.find(isElementVisibleInViewport); } let lastMarkdownPosition = { lineBegin: 1, columnBegin: 1, lineEnd: 1, columnEnd: 1 }; function scrollCallback() { const candidate = currentTopMarkdownElement(); if (!candidate) { return; } const result = positionOfMarkdownElement(candidate); if (result.lineBegin === lastMarkdownPosition.lineBegin && result.columnBegin === lastMarkdownPosition.columnBegin && result.lineEnd === lastMarkdownPosition.lineEnd && result.columnEnd === lastMarkdownPosition.columnEnd) { return; } result.scrollTop = document.body.scrollTop; lastMarkdownPosition = result; // console.log(`webview scrolled to ${result.lineBegin}:${result.columnBegin}`); window.webkit.messageHandlers.com_vimr_tools_preview_markdown.postMessage(result); } let lastKnownScrollPos = 0; let ticking = false; window.addEventListener('scroll', () => { lastKnownScrollPos = window.scrollY; if (!ticking) { window.requestAnimationFrame(() => { if (lastKnownScrollPos >= 0 && !suppressNextScrollEvent) { scrollCallback(); } suppressNextScrollEvent = false; ticking = false; }); } ticking = true; }); // Forward search function scrollToPosition(row, column) { const entries = toArray(document.querySelectorAll("[data-sourcepos]")) .map(element => { const position = positionOfMarkdownElement(element); return { element: element, position: position, rowDistance: Math.abs(row - position.lineBegin), columnDistance: Math.abs(column - position.columnBegin) }; }); const minRowDistance = entries.reduce((result, entry) => { return Math.min(result, entry.rowDistance) }, Number.MAX_SAFE_INTEGER); const entriesWithMinRowDistance = entries.filter(entry => entry.rowDistance === minRowDistance); const minColumnDistance = entriesWithMinRowDistance.reduce((result, entry) => { return Math.min(result, entry.columnDistance) }, Number.MAX_SAFE_INTEGER); const candidateEntry = entriesWithMinRowDistance.find(entry => entry.columnDistance === minColumnDistance); if (!candidateEntry) { return; } const element = candidateEntry.element; if (isElementVisibleInViewport(element)) { return; } let {x, y} = scrollPosition(element); suppressNextScrollEvent = true; window.scrollTo(x, y); // console.log(`scrolled webview to ${x}:${y}`); return document.body.scrollTop } function scrollPosition(element) { let {x, y} = { x: 0, y: 0 }; let curEl = element; while (curEl) { x += curEl.offsetLeft; y += curEl.offsetTop; curEl = curEl.offsetParent; } return { x: x, y: y }; } {{ title }} {{ body }} Prism.highlightAll(); ``` -------------------------------- ### Customize Menu Key Bindings Source: https://github.com/qvacua/vimr/wiki/VimR-MacVim Define custom key bindings for menu items in the ~/.vimr_rc file. Setting a binding to blank disables the default menu shortcut, forwarding the key combination to Vim. ```text global.keybinding.menuitem.file.new = @-a global.keybinding.menuitem.file.open-in-tab = @-$-a global.keybinding.menuitem.file.save-as = # more keys described below ``` ```text global.keybinding.menuitem.file.save-as = ``` -------------------------------- ### Store Notary Credentials Source: https://github.com/qvacua/vimr/blob/master/DEVELOP.md Command to store Apple notary credentials in the keychain. ```bash xcrun notarytool store-credentials "apple-dev-notar" \ --apple-id \ --team-id \ --password ``` -------------------------------- ### Simple Diacritic Input Sequence Source: https://github.com/qvacua/vimr/blob/master/docs/notes-on-cocoa-text-input.md Demonstrates the sequence of calls for entering a diacritic character like 'ü' using the NSTextInputClient protocol. ```swift setMarkedText("¨", selectedRange NSRange(1, 0), replacementRange: NSRange(NSNotFound, 0)) ``` ```swift insertText("ü", replacementRange: NSRange(NSNotFound, 0)) ``` -------------------------------- ### Apply Gitignore Pattern Matching in Swift Source: https://context7.com/qvacua/vimr/llms.txt Utilizes the Ignore module to filter files based on .gitignore and .ignore files, supporting hierarchical structures and global patterns. ```swift import Ignore // Create ignore from directory with .gitignore and .ignore files let projectRoot = URL(fileURLWithPath: "/path/to/project") let ignore = Ignore( base: projectRoot, parent: nil, ignoreFileNames: [".ignore", ".gitignore"] ) // Check if file should be excluded let nodeModules = URL(fileURLWithPath: "/path/to/project/node_modules", isDirectory: true) if ignore?.excludes(nodeModules) == true { print("node_modules is ignored") } // Check specific files let buildArtifact = URL(fileURLWithPath: "/path/to/project/build/output.o") let sourceFile = URL(fileURLWithPath: "/path/to/project/src/main.swift") print("build/output.o ignored: \(ignore?.excludes(buildArtifact) ?? false)") print("src/main.swift ignored: \(ignore?.excludes(sourceFile) ?? false)") // Use global gitignore (from ~/.config/git/ignore) if let globalIgnore = Ignore.globalGitignore(base: projectRoot) { print("Has global gitignore patterns") } // Hierarchical ignore with parent let subDir = projectRoot.appendingPathComponent("packages/ui") let childIgnore = Ignore.parentOrIgnore( for: subDir, withParent: ignore, ignoreFileNames: [".gitignore"] ) // Filter a list of URLs let allFiles: [URL] = getFilesRecursively(from: projectRoot) let visibleFiles = allFiles.filter { url in !(ignore?.excludes(url) ?? false) } ``` -------------------------------- ### VimR Command Line Tool Usage Source: https://github.com/qvacua/vimr/wiki/VimR-MacVim Common commands for the vimr CLI tool to open files, navigate to lines, or display help. ```bash $ vimr file1 file2 ... # opens file1, file2, ... in tabs in the front most window. $ vimr -n file1 file2 ... # opens file1, file2, ... in tabs in a new window. $ vimr -m file1 file2 ... # opens file1, file2, ... in separate new windows $ vimr -l 10 file1 # go to line 10 of file1 (file1 is either opened or brought to front) $ vimr -h # show help ``` -------------------------------- ### Git Configuration for VimR Difftool with DirDiff Source: https://github.com/qvacua/vimr/wiki/How-to-use-VimR-as-git-difftool-(with-DirDiff.vim) Configure git to use VimR as the difftool, specifically invoking the DirDiff integration command. This configuration should be placed in `~/.gitconfig`. ```gitconfig [difftool "vimrdiff"] cmd = vimr --wait --nvim '+au GUIEnter * execute "DirDiff" argv(0) argv(1)' '+au GUIEnter * VimRDirDiff' $LOCAL $REMOTE [diff] tool = vimrdiff ``` -------------------------------- ### VimR Temporary Maximized Diff Window Command Source: https://github.com/qvacua/vimr/wiki/How-to-use-VimR-as-git-difftool-(with-DirDiff.vim) Define a Vim command to temporarily maximize the VimR window, hide tools, and prevent settings persistence. Place this in `~/.config/nvim/ginit.vim`. ```viml function! s:VimRTempMaxWin() abort VimRMakeSessionTemporary " The tools, tool buttons and window settings are not persisted VimRHideTools VimRMaximizeWindow endfunction command! -nargs=0 VimRTempMaxWin call s:VimRTempMaxWin() ``` -------------------------------- ### Configure Tab Selection Bindings Source: https://github.com/qvacua/vimr/wiki/VimR-MacVim Modify the active state and modifier keys for tab selection in ~/.vimr_rc. ```text global.keybinding.select-nth-tab.active = false global.keybinding.select-nth-tab.modifier = @-$ ``` -------------------------------- ### Korean Hangul Input Sequence Source: https://github.com/qvacua/vimr/blob/master/docs/notes-on-cocoa-text-input.md Illustrates the method call sequence for composing Korean characters, involving repeated calls to setMarkedText and final insertion. ```swift selectedRange() ``` ```swift attributedSubstringForProposedRange(_:actualRange:) ``` ```swift setMarkedText("ㅎ", selectedRange: NSRange(1, 0) replacementRange:NSRange(NotFound, 0)) ``` ```swift setMarkedText("하", selectedRange: NSRange(1, 0), replacementRange: NSRange(NotFound, 0)) ``` ```swift setMarkedText("핱", selectedRange: NSRange(1, 0), replacementRange: NSRange(NotFound, 0)) ``` ```swift insertText("하", replacementRange: NSRange(NotFound, 0)) ``` ```swift setMarkedText("태", selectedRange: NSRange(1, 0), replacementRange: NSRange(NotFound, 0)) ``` -------------------------------- ### Implement TabBar Component in Swift Source: https://context7.com/qvacua/vimr/llms.txt Defines a custom tab data model conforming to TabRepresentative and configures the TabBar with themes and event handlers. ```swift import Tabs // Define tab data model struct MyTab: TabRepresentative { var title: String var isSelected: Bool var identifier: Int func hash(into hasher: inout Hasher) { hasher.combine(identifier) } static func == (lhs: MyTab, rhs: MyTab) -> Bool { lhs.identifier == rhs.identifier } } // Create tab bar with theme let theme = TabBar.Theme( tabBarBackgroundColor: .windowBackgroundColor, tabBackgroundColor: .controlBackgroundColor, selectedTabBackgroundColor: .selectedContentBackgroundColor, tabTextColor: .textColor, selectedTabTextColor: .selectedTextColor, separatorColor: .separatorColor, separatorThickness: 1.0, tabSpacing: 0.0 ) let tabBar = TabBar(withTheme: theme) // Set up handlers tabBar.selectHandler = { index, tab, allTabs in print("Selected tab \(index): \(tab.title)") } tabBar.closeHandler = { index, tab, allTabs in print("Close tab \(index): \(tab.title)") // Return to allow close, or handle cancellation } tabBar.reorderHandler = { newIndex, tab, allTabs in print("Tab \(tab.title) moved to index \(newIndex)") } // Update tabs let tabs = [ MyTab(title: "main.swift", isSelected: true, identifier: 1), MyTab(title: "AppDelegate.swift", isSelected: false, identifier: 2), MyTab(title: "README.md", isSelected: false, identifier: 3) ] tabBar.update(tabRepresentatives: tabs) // Update theme dynamically tabBar.update(theme: newTheme) // Set current working directory for relative path display tabBar.cwd = "/Users/developer/project" ``` -------------------------------- ### LaTeX Inverse Search Command Source: https://github.com/qvacua/vimr/wiki/VimR-MacVim Use the bundled vimr command-line tool to trigger inverse search for LaTeX files. ```bash vimr -l %line "%file" ``` -------------------------------- ### Detect VimR vs MacVim in vimrc Source: https://github.com/qvacua/vimr/wiki/VimR-MacVim Use conditional checks in your .vimrc to apply environment-specific configurations. ```vim if has("gui_vimr") " VimR specific stuff endif if has("gui_macvim") " MacVim specific stuff endif ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.